Tomcat中很多组件具有生命周期,如初始化、启动、关闭,这些组件的生命周期具有共性,因此Tomcat中将其抽象为接口Lifecycle,来控制组件的生命周期,它通过 事件机制 实现各个容器间的内部通讯。
Lifecycle接口的方法:
继承关系图:
Tomcat的类加载器架构
先是Bootstrap.initClassLoaders()设置类加载器:CommonClassLoader 、ServerClassLoader 、SharedClassLoader,
/common(存放Tomcat与所有Web应用程序共用的类库)、
/server(只Tomcat使用、而所有Web应用程序不可见的)、
/shared(Tomcat不可见、而所有Web应用程序共用)。
另外,在后面初始化每个Web应用程序解析web.xml时,会创建WebappClassLoader,只有对应的Web应用程序可见,加载对应Web应用程序的/WEB-INF/lib里的类库。
所以默认情况下,Tomcat类加载器架构如下:
Bootstrap类加载器为Java虚拟机提供,包含JDK基本运行时类,
而System类加载器用于Tomcat启动初始化(通常忽略)
Tomcat类加载器架构是按照经典的”双亲委派模型”来实现的,即:当类加载器被要求加载特定的类或资源时,它首先将请求委托给父类加载器,然后只有当父类加载器找不到请求的类或资源时,它才在自己的存储库中查找。
Tomcat的类加载器架构的好处是可以按需要实现Tomcat与Web应用程序、以及不现Web应用程序之间的类库共享与隔离,如常用的Spring等类库可以放到共享目录,为多个Web应用程序共用;而”双亲委派模型”也是JDK类加载器的架构,可以有效组织类库的层次结构,避免一个类被不同加载器加载多次(注意,同一个类文件被不同加载器加载表示不同的类)。
简述:
整个启动加载过程的调用队列如下:
org.apache.catalina.startup.Bootstrap#main
->org.apache.catalina.startup.Bootstrap#init
->org.apache.catalina.startup.Bootstrap#load
-->org.apache.catalina.startup.Catalina#load
--->org.apache.catalina.core.StandardServer#init
---->org.apache.catalina.core.StandardService#init
----->org.apache.catalina.connector.Connector#init
----->org.apache.catalina.core.StandardEngine#init
->org.apache.catalina.startup.Bootstrap#start
-->org.apache.catalina.startup.Catalina#start 通过反射调用
--->org.apache.catalina.core.StandardServer#start
---->org.apache.catalina.core.StandardService#start
----->org.apache.catalina.core.StandardEngine#start
----->org.apache.catalina.Executor#start
----->org.apache.catalina.connector.Connector#start
Tomca初始化
Catalina.load()中调用Server组件的初始化函数,Server.initInternal()又调用内部包含的Service组件的初始化…以此类推,按配置文件的组件结构顺序初始化
沿着Server—>Service->Container(Engine—>Host—>Context—>Wrapper—>Servlet)这一核心顺序一一总结Tomcat初始化的过程。
[1] StandardServer.initInternal():
(1)创建和注册(注册到MBeanServer)全局的StringCache;
(2)初始化GlobalNamingResources;
(3)初始化该Server包含的所有service组件(虽然通常都只有一个名为“Catalina”的service);
[2] StandardService.initInternal():
这一层其实包含了很多重要组件的初始化:Container,Executor,MapperListener,Connector;
(1)初始化容器,从容器的最外层(Engine)开始,一层层开始;
(2)如果定义了org.apache.catalina.Executor,初始化Executor。还是说明一下,它实现了J.U.C中的Executor,定义一个为所有Connector共享的线程池(因此在server.xml中Executor必须定义在Connector,因为前面提到了解析server.xml使用SAX的方式);
(3)初始化mapperListener,MapperListener是Tomcat中用来保存整个容器必要结构信息用于将请求URL映射到对应容器;
(4)初始化Connector,这个过程会初始化每个Connector包含的ProtocolHandldr等组件,让连接处理部分做好准备;
部分源代码如下:
//org.apache.catalina.startup.Tomcat#init
public void init() throws LifecycleException {
getServer();
getConnector();
server.init();
}
//org.apache.catalina.startup.Tomcat#getConnector
public Connector getConnector() {
getServer();
connector = new Connector("HTTP/1.1");