Tomcat的启动
Tomcat的基本结构
Tomcat容器分为四个等级,Engine--Host--Servlet—Context(一个Context对应一个web工程)
一个 Context 对应一个 Web 工程,所以我们在Tomcat根目录的webapps文件夹路径下面经常会看到除了我们自己部署的web,还有若干其他Tomcat自带的web,不同的web工程都会对应在Tomcat里面的context容器。
Tomcat启动时序图
Tomcat的启动( Tomcat是采用了一种观察者模式的设计方式,所有的容器都会继承 Lifecycle 接口,它管理容器的整个生命周期,所有容器的的修改和状态的改变都会由它去通知已经注册的观察者(Listener))
1.Tomcat的启动是从顶层开始一直到Engine到Host再到StandardContext(这里的context我可以理解为就是对应每个web工程的容器了)
2.当 Context 容器初始化状态设为 init 时,添加在 Context 容器的 Listener 将会被调用。ContextConfig 继承了 LifecycleListener 接口,ContextConfig 类会负责整个 Web 应用的配置文件的解析工作。
Web应用的启动
3.Tomcat调用ContextConfig的configureStart方法解析web.xml的所有属性(包括contextConfigLocation,ContextLoaderListener),将这些属性保存到WebXml对象中
4.Tomcat会创建一个ServletContext容器,并将WebXml对象的属性设置到servletContext中
5.Context容器会创建web.xml配置的监听器类Listener,并且监听器类必须要实现ServletContextListener接口
public interface ServletContextListener extends EventListener { //初始化Spring容器 void contextInitialized(ServletContextEvent var1); //用于关闭应用前释放资源,比如说数据库连接的关闭。 void contextDestroyed(ServletContextEvent var1); }
- web.xml 属性都被解析到 Context 中,所以说 Context 容器才是真正运行 Servlet 的 Servlet 容器。
- web.xml作用:容器的配置属性由应用的 web.xml 指定
Spring容器的启动
流程图:
6.ContextLoaderListener实现了用来监听ServletContext事件的ServletContextListener 这个接口,如果 ServletContext 状态发生变化,将会触发产生对应的ServletContextEvent,然后调用监听器的不同的方法。
public class ContextLoaderListener extends ContextLoader implementsServletContextListener { ... //实现了ServletContextListener的初始化接口 public void contextInitialized(ServletContextEvent event) { this.initWebApplicationContext(event.getServletContext()); } //同上 public void contextDestroyed(ServletContextEvent event) { this.closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); } }