Tomcat源码系列2--Tomcat启动流程2

下面是standardEngine的启动和connector的启动

● standardEngine的启动 (1) 首先是StandardEngine.start()被调用

public void start() throws LifecycleException { 
       // Standard container startup   
      //进行logger,manager,cluster,realm,resource的启动   
       super.start(); 
}

 (2) super.start()--->org.apache.catalina.core.ContainerBase#start()

public synchronized void start() throws LifecycleException { 
//(省略)  server.xml中配置应用组件的启动    
//StandardHost容器的启动,   
        Container children[] = findChildren();   
        for (int i = 0; i < children.length; i++) {   
            if (children[i] instanceof Lifecycle)   
                ((Lifecycle) children[i]).start();   
        }     

    //StandardPipeline的启动(容器与容器间的管道)   
        if (pipeline instanceof Lifecycle)   
            ((Lifecycle) pipeline).start();  
}

(3) StandardHost.start()被调用 

public synchronized void start() throws LifecycleException { 
//返回到以上的containerBase#start执行pipeline   
      super.start();  
}

  (4) StandardPipeline#start

public synchronized void start() throws LifecycleException { 
       // 将会调用HostConfig#start方法   
       lifecycle.fireLifecycleEvent(START_EVENT, null);   
  
       // Notify our interested LifecycleListeners   
       lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);   
}

 (5)  HostConfig#start

public void start() {  
          //部暑webapps   
          deployApps();            
  }

(6) HostConfig#deployApps 

protected void deployApps() {   
       File appBase = appBase();   
       File configBase = configBase();   
       // Deploy XML descriptors from configBase   
       deployDescriptors(configBase, configBase.list());   
       // Deploy WARs, and loop if additional descriptors are found   
       deployWARs(appBase, appBase.list());   
       // Deploy expanded folders   
       deployDirectories(appBase, appBase.list());             
   }

   (7) deployWARs

protected void deployWARs(File appBase, String[] files) { 
…… 
deployWAR(contextPath, dir, file);          
  }

(8) deployWAR

protected void deployWAR(String contextPath, File war, String file) { 
if (context instanceof Lifecycle) {   
  // (省略) 
            Class clazz = Class.forName(host.getConfigClass());   
            LifecycleListener listener =   
                (LifecycleListener) clazz.newInstance();   
            ((Lifecycle) context).addLifecycleListener(listener);   
        }   
        context.setPath(contextPath);   
        context.setDocBase(file);   
        //以下这一步跟进去,,StandardContext的启动   
        host.addChild(context);         
  }

 

(9)StandardContext#start

在Context的启动过程中,主要完成了以下任务。

----------------------------------------------------------------------------------------------------------------------

a)设置webapp的具体目录webappResources。

b)postWorkDirectory(),创建临时文件目录。Tomcat下面有一个work目录,用来存放临时文件。

c)触发START_EVENT事件监听,在这个事件监听里面会启动ContextConfig的start()事件,ContextConfig是用来配置web.xml的。

d)为context创建welcomefiles,通常是这三个启动文件:index.html、index.htm、index.jsp

e)配置filter

f)启动带有<load-on-startup>的Servlet。

g)注册JMX。

----------------------------------------------------------------------------------------------------------------------

至此,Container启动完毕,下面是connector的启动。

●connector的启动

(1) org.apache.catalina.connector.Connector.start() 
public void start() throws LifecycleException { 
           // Http11Protocol的启动 
            protocolHandler.start(); 
}

  (2) Http11Protocol#start 

public void start() throws Exception { 
try {   
            //到了终点的启动   
            endpoint.start();   
        } catch (Exception ex) {   
            log.error(sm.getString("http11protocol.endpoint.starterror"), ex);   
            throw ex;   
        }

   (3) JIoEndPoint#start 

public void start()   
        throws Exception {            
              
            for (int i = 0; i < acceptorThreadCount; i++) {   
        //这里的acceptor是一个线程,里面是一个serversocket的启动   
                Thread acceptorThread = new Thread(new Acceptor(), getName() + "-Acceptor-" + i);   
                acceptorThread.setPriority(threadPriority);   
                acceptorThread.setDaemon(daemon);   
                acceptorThread.start();   
            }   
        }

    (4) Acceptor#run

public void run() {               
// Accept the next incoming connection from the server socket   
               try {   
          //这里进行了accept(),等待客户端消息,进行接收   
                   Socket socket = serverSocketFactory.acceptSocket(serverSocket);   
                   serverSocketFactory.initSocket(socket);   
                   // Hand this socket off to an appropriate processor   
                   if (!processSocket(socket)) {   
                       // Close socket right away   
                       try {   
                           socket.close();   
                       } catch (IOException e) {   
                           // Ignore   
                       }   
                   }   
               }catch ( IOException x ) {   
                   if ( running ) log.error(sm.getString("endpoint.accept.fail"), x);   
               } catch (Throwable t) {   
                   log.error(sm.getString("endpoint.accept.fail"), t);   
               }   
}

至此Connector.start方法调用完毕。整个server启动完毕。

相关推荐