有点乱,基本上是看代码时的笔记。
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