Tomcat啓動(二)

這篇講Catalina.initialize()的過程,下面是相關的UML

 // Start the new server
        if (server instanceof Lifecycle) { //判斷Server是否實現Lifecycle接口,如果實現的話,調用initialize
            try {
                server.initialize();
            } catch (LifecycleException e) {
                log.error("Catalina.start", e);
            }
        }

2.StandardServer.initialize()

 /**
     * Invoke a pre-startup initialization. This is used to allow connectors
     * to bind to restricted ports under Unix operating environments.
     * 調用開始前的初始化,用來綁定在unix操作系統環境下受限制的端口
     */
    public void initialize()
        throws LifecycleException 
    {
        if (initialized) {
                log.info(sm.getString("standardServer.initialize.initialized"));
            return;
        }
        lifecycle.fireLifecycleEvent(INIT_EVENT, null);//觸發init事件
        initialized = true;

        if( oname==null ) { //把server對象註冊到mbean裏面,後面創建的變量一般都是註冊到mbean,方便管理
            try {
                oname=new ObjectName( "Catalina:type=Server");
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null );
            } catch (Exception e) {
                log.error("Error registering ",e);
            }
        }
        
        // Register global String cache
        try {
            ObjectName oname2 = 
                new ObjectName(oname.getDomain() + ":type=StringCache");
            Registry.getRegistry(null, null)
                .registerComponent(new StringCache(), oname2, null );
        } catch (Exception e) {
            log.error("Error registering ",e);
        }

        // Initialize our defined Services
        for (int i = 0; i < services.length; i++) {
            services[i].initialize();
        }
    }

3.StandardService.initialize()

public void initialize()
            throws LifecycleException
    {
        // Service shouldn't be used with embeded, so it doesn't matter
        if (initialized) {
            if(log.isInfoEnabled())
                log.info(sm.getString("standardService.initialize.initialized"));
            return;
        }
        initialized = true;

        if( oname==null ) {
            try {
                // Hack - Server should be deprecated...
                Container engine=this.getContainer();
                domain=engine.getName();
                oname=new ObjectName(domain + ":type=Service,serviceName="+name);
                this.controller=oname;
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null);
                
                Executor[] executors = findExecutors();
                for (int i = 0; i < executors.length; i++) {
                    ObjectName executorObjectName = 
                        new ObjectName(domain + ":type=Executor,name=" + executors[i].getName());
                    Registry.getRegistry(null, null)
                        .registerComponent(executors[i], executorObjectName, null);
                }
                
            } catch (Exception e) {
                log.error(sm.getString("standardService.register.failed",domain),e);
            }
            
            
        }
        if( server==null ) {
            // Register with the server 
            // HACK: ServerFactory should be removed...
            
            ServerFactory.getServer().addService(this);
        }
               

        // Initialize our defined Connectors
        synchronized (connectors) {//這裏在server.xml配置了兩個connector.HTTP/1.1、AJP/1.3
                for (int i = 0; i < connectors.length; i++) {
                    connectors[i].initialize();
                }
        }
    }

4.Connector.initialize()

public void initialize()
        throws LifecycleException
    {
        if (initialized) {
            if(log.isInfoEnabled())
                log.info(sm.getString("coyoteConnector.alreadyInitialized"));
           return;
        }

        this.initialized = true;

        if( oname == null && (container instanceof StandardEngine)) {
            try {
                // we are loaded directly, via API - and no name was given to us
                StandardEngine cb=(StandardEngine)container;
                oname = createObjectName(cb.getName(), "Connector");
                Registry.getRegistry(null, null)
                    .registerComponent(this, oname, null);
                controller=oname;
            } catch (Exception e) {
                log.error( "Error registering connector ", e);
            }
            if(log.isDebugEnabled())
                log.debug("Creating name for connector " + oname);
        }

        // Initializa adapter
        adapter = new CoyoteAdapter(this);//設置爲Coyote connector
        protocolHandler.setAdapter(adapter);

        IntrospectionUtils.setProperty(protocolHandler, "jkHome",
                                       System.getProperty("catalina.base"));

        try {
            protocolHandler.init();
        } catch (Exception e) {
            throw new LifecycleException
                (sm.getString
                 ("coyoteConnector.protocolHandlerInitializationFailed", e));
        }
    }

上面的調用了protocolHandler.init方法,那麼protocolHandler是怎麼實例化的呢?

 public Connector(String protocol)
        throws Exception {
        setProtocol(protocol);
        // Instantiate protocol handler
        try {
            Class clazz = Class.forName(protocolHandlerClassName);
            this.protocolHandler = (ProtocolHandler) clazz.newInstance();
        } catch (Exception e) {
            log.error
                (sm.getString
                 ("coyoteConnector.protocolHandlerInstantiationFailed", e));
        }
    }

 public void setProtocol(String protocol) {

        // Test APR support         initializeAPR();

        if (aprInitialized) {             if ("HTTP/1.1".equals(protocol)) {                 setProtocolHandlerClassName                     ("org.apache.coyote.http11.Http11AprProtocol");             } else if ("AJP/1.3".equals(protocol)) {                 setProtocolHandlerClassName                     ("org.apache.coyote.ajp.AjpAprProtocol");             } else if (protocol != null) {                 setProtocolHandlerClassName(protocol);             } else {                 setProtocolHandlerClassName                     ("org.apache.coyote.http11.Http11AprProtocol");             }         } else {             if ("HTTP/1.1".equals(protocol)) {                 setProtocolHandlerClassName                     ("org.apache.coyote.http11.Http11Protocol");             } else if ("AJP/1.3".equals(protocol)) {                 setProtocolHandlerClassName                     ("org.apache.jk.server.JkCoyoteHandler");             } else if (protocol != null) {                 setProtocolHandlerClassName(protocol);             }         }

    }

根據server.xml配置的connector協議實例化相應的Protocol.

5.Http11Protocol.init()

public void init() throws Exception {
        endpoint.setName(getName());
        endpoint.setHandler(cHandler);

        // Verify the validity of the configured socket factory
        try {
            if (isSSLEnabled()) {
                sslImplementation =
                    SSLImplementation.getInstance(sslImplementationName);
                socketFactory = sslImplementation.getServerSocketFactory();
                endpoint.setServerSocketFactory(socketFactory);
            } else if (socketFactoryName != null) {
                socketFactory = (ServerSocketFactory) Class.forName(socketFactoryName).newInstance();
                endpoint.setServerSocketFactory(socketFactory);
            }
        } catch (Exception ex) {
            log.error(sm.getString("http11protocol.socketfactory.initerror"),
                      ex);
            throw ex;
        }

        if (socketFactory!=null) {
            Iterator<String> attE = attributes.keySet().iterator();
            while( attE.hasNext() ) {
                String key = attE.next();
                Object v=attributes.get(key);
                socketFactory.setAttribute(key, v);
            }
        }
        
        try {
            endpoint.init();
        } catch (Exception ex) {
            log.error(sm.getString("http11protocol.endpoint.initerror"), ex);
            throw ex;
        }
        if (log.isInfoEnabled())
            log.info(sm.getString("http11protocol.init", getName()));

    }

這裏判斷服務器是否打開SSL,如果沒有,就調用JIoEndpoint.init()

6.JIoEndpoint.init()

/**
     * 創建server socket
     */
    public void init()
        throws Exception {

        if (initialized)
            return;
        
        // Initialize thread count defaults for acceptor
        if (acceptorThreadCount == 0) {
            acceptorThreadCount = 1;
        }
        if (serverSocketFactory == null) {
            serverSocketFactory = ServerSocketFactory.getDefault();
        }
        if (serverSocket == null) {
            try {
                if (address == null) {
                    serverSocket = serverSocketFactory.createSocket(port, backlog);
                } else {
                    serverSocket = serverSocketFactory.createSocket(port, backlog, address);
                }
            } catch (BindException be) {
                if (address == null)
                    throw new BindException(be.getMessage() + "<null>:" + port);
                else
                    throw new BindException(be.getMessage() + " " +
                            address.toString() + ":" + port);
            }
        }
        //if( serverTimeout >= 0 )
        //    serverSocket.setSoTimeout( serverTimeout );
        
        initialized = true;
        
    }

這裏還不能監聽客戶端,沒有accept




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章