分享Tomcat源码系列二

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

● standardEngine的启动

(1) 首先是StandardEngine.start()被调用

Java代码

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

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

Java代码

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()被调用

Java代码

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

(4) StandardPipeline#start

Java代码

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

Java代码

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

Java代码

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

Java代码

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

Java代码

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) 设置web app的具体目录webappResources。

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

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

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

e) 配置filter

f) 启动带有的Servlet。

g) 注册JMX。

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

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

● connector的启动

(1) org.apache.catalina.connector.Connector.start()

Java代码

public void start() throws LifecycleException {     
           // Http11Protocol的启动     
            protocolHandler.start();     
}  
(2) Http11Protocol#start

Java代码

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

Java代码

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

Java代码

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启动完毕。

猜你喜欢

转载自fjg0427.iteye.com/blog/1662020