`
mooncui
  • 浏览: 71289 次
社区版块
存档分类
最新评论

Tomcat 启动过程

    博客分类:
  • Java
阅读更多

有点乱,基本上是看代码时的笔记。

StandardServer.init
StandardService.initialize
Http11Protocol.init
JIoEndpoint.init
connector.initialize()
JkCoyoteHandler.init
JkMain.init
   

这里的几个类基本都实现了Lifecycle接口,这个接口非常重要。
StandardServer.start()       
StandardService.start()
StandardEngine.start()  --StandardEngine[Catalina], it is Container
    ContainerBase.start()  : 分别start 其 children
        StandardHost.start()
                在HostConfig.deployDirectories(当然还有deployWARs)中读出若干目录,跟别deployDirectory各个,在这里为每个

应用例如examples,创建一个Context,这里是用默认的class loader的,即:
                普通的context = (Context) Class.forName(contextClass).newInstance();  并创建ContextConfig来监听其lifecycle的事件,并

使其成为StandardHost的child,
           |        利用lifecycleEvent -->start HostConfig
    child|
        StandardContext.init()
        StandardContext.start()
                利用lifecycleEvent-->start ContextConfig,  ContextConfig start的时候,重点有两个:
                      defaultWebConfig();   -- 解析conf/web.xml 及 conf\Catalina\localhost\web.xml.default文件
                      applicationWebConfig(); -- 解析应用下的web.xml
               
                      都是用Digester来解析web.xml(默认是此文件)的(Digester的解析,主要利用WebRuleSet这个类,这里的用法比较复杂,暂放在这里),从里面读到servlet的配置就将他作为一个child加到Context中。每个servlet用StandardWrapper来代理,看它的声明:
        public class StandardWrapper     extends ContainerBase    implements ServletConfig, Wrapper, NotificationEmitter
       
        每个servlet也是container,它的context是ApplicationContextFacade (implements ServletContext)
        由于每个应用有一个Context,而每个Context的start方法中都进行了defaultWebConfig,而这里的conf/web.xml和web.xml.default是所有应用共同的,说明如果一个tomcat server在启动的时候,如果有多个应用,那么default web.xml是解析了多遍,而且在各个应用的Context中都有default web.xml 中配置的servlet(默认是default和jsp两个)实例。

        每个Context会有一个loader,如果没有,就加一个WebappLoader,这里有classLoader(WebappClassLoader), 还有classLoader需要的路径和jar file,包括work目录lib目录中的jar files,
        所以是每个Context有自己的class loader和domain的。
        在Context的start中做了很多事情,包括listenner.start(),pipeline.start(),manager.start(), filterStart()
                start listenner的时候,用Context中的class loader,另外可能需要处理Annotation。
                在start filter的时候,如果是Tomcat自带的filter,就用当前的class loader,否则用Context中的class loader,也可能需要处理Annotation。
       
        每个Context有个Realm,这个有待进一步了解。

 

参看server.xml的配置              
<Server port="8005" shutdown="SHUTDOWN">
    <Listener>
    <GlobalNamingResource
        <Resource name="UserDatabase" auth="Container"
    </GlobalNamingResources>
    <Service name="Catalina">    处理
        <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
        <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
        <Engine name="Catalina" defaultHost="localhost">
             <Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
             <Host name="localhost"  appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false"/>
        </Engine>
    </Service>
</Server>                           

在server.xml中默认是定义了两个Connector的,一个事在8080(protocol="HTTP/1.1"),一个是在8009(protocol="AJP/1.3")
Connector.start()
Http11Protocol.start()
JIoEndpoint.start():  new 了一个WorkerStack(Worker(Runable对象)数组) new 了一个thread,运行Acceptor对象,用来在后台监听TCP/IP连接请求,然后将

请求分配给一个合适的processor。

这时看线程有三个:
main
ContainerBackgroundProcessor[StandardEngine(Catalina)]
http-8080-Acceptor-0

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics