听说了很多次,tomcat是一个 servlet容器,也用了好些框架,总是配置这配置那的,心里也充满疑惑,今天就跟着大牛的脚步整理整理它们两个到底是怎么回事,不奢望全部弄懂,至少不能像以前一样混混沌沌的。
上午了解了tomcat中大致启动的原理,现在看来不够详细。这里再将上午的思路接着捋一捋。
之后会init StandardEngine,再然后是init connector。 红色部分是上午没注意到的。
之后就是start的作用了,根据ibm的tomcat运行时序图,(https://www.ibm.com/developerworks/cn/java/j-lo-servlet/image003.jpg) 可以知道server 去启动 service,service 启动 engine,engine启动host,host启动context. 到这里才是到了上午的start方法中的内容了。 在启动context的时候,会完成每个Web应用项目的配置解析。随后会完成Web应用的初始化工作。
到了这里,还是没有看到servlet的影子。
原来tomcat容器分为四个等级: 第一级为container 包含 server,以及 service,它们是一个一对多的关系。 第二级为Engine,第三级为 Context,第四级为 wrapper. 真正管理servlet容器的是 context容器。 一个Context对应一个web工程,context初始化的时候会去寻找web.xml,存在则解析。 解析过程中,会将web.xml中的各个配置项解析成相应的属性保存在WebXml对象中。然后将WebXml中的属性设置到Context容器中,包括创建servlet对象,filter,listener等。 WebXml对象的configureContext()方法将servlet包装成Context容器中的StandardWrapper。 因此,一个web应用对应一个context容器,容器的配置属性由应用的web.xml指定(其执行逻辑:首先会找globalWebXml,其搜索路径是在engine的工作目录下寻找一下两个文件中的任意一个,org/apache/catalina/startup/NO_DEFAULT_XML 或者 conf/web.xml; 接着会找hostWebXml,位于 System.getProperty("catalina.base")/conf/${EngineName}/${HostName}/web.xml.default; 接着学着配置文件的webRoot/WEB-INF/web.xml)。
注意:在context的createWrapper()的时候,会设置Servlet的各种属性,包括servletClass。
创建Servlet实例的方法是从Wrapper.loadServlet()开始的。loadServlet方法要完成的就是获取servletClass,然后把它交给InstanceManager()去创建一个基于servletClass.class的对象。如果这个Servlet配置了jsp-file,那么这个servletClass就是conf/web.xml中定义的org.apache.jasper.servlet.JspServlet了。
Wrapper.initServlet方法中,这个方法就是调用了Servlet的init的方法,同时把包装了StandardWrapper对象的StandardWrapperFacade作为ServletConfig传给 Servlet. 事实上Servlet从被web.xml中解析到完成初始化,过程非常复杂,中间由很多的过程,包括各种容器状态的转换引起的监听事件的触发,各种访问权限的控制,和一些不可预料的错误发生的判断行为等。
servelt创建和初始化的完整时序图: https://www.ibm.com/developerworks/cn/java/j-lo-servlet/image007.jpg