以Tomcat为例解释:
在Tomcat容器等级中,Context容器直接管理Servlet在容器中的包装类wrapper,故Context运行方式直接影响servlet
一个Context应用对应一个web工程
在添加一个web应用的时候,会创建一个StandardContext容器,并给这个容器必要的参数,url和path对应的是Tomcat中的访问路径和应用的物理路径。整个配置中最重要的是ContextConfig,这个类主要负责整个Web应用配置的解析工作,最后将这个Context容器加到父容器Host中。
Tomcat的启动逻辑
Tomcat的启动逻辑是基于观察者模式设计的,所有容器都会继承Lifecycle接口,它管理着容器的整个生命周期,所有容器的修改和状态的改变都会有他去通知已经注册的观察者。
9.1 Servlet容器的启动过程
当Context容器初始化状态设为init时,添加到Context容器的Listener将会被调用。ContextConfig继承了LifecycleListener接口,他是在调用Tomcat.addWebapp时被加入到StandardContext容器中。ContextConfighi负责整个web应用的配置文件的解析工作。
ContextConfiginit方法主要完成:
创建用于解析XML配置文件的contextDigester对象
读取默认的context.xml文件
读取默认的Host配置文件
读取默认的Context配置文件
设置Context的DocBase
当init完成之后,ContextConfig会执行startInternal方法。执行流程如下
创建读取资源文件的对象
创建ClassLoader对象
设置应用程序的工作牡蛎
启动相关的辅助类,logger,realm,resources
修改启动状态,通知感兴趣的观察者
子容器的初始化
获取ServletContext并设置必要的参数
初始化“load on startup”的servlet
9.2 web应用的初始化工作
Tomcat在启动的时候会找globalWebXml(在engine工作目录下conf/web.xml中),接着找hostWeXml(在System.getProperty("catalina.base")/conf/${EngineName}/${HostName}/web.xml/default中)进而寻找应用配置文件web.xml,读取并存放在WebXml目录中。
为什么servlet包装成StandardWrapper,而不是servlet?
之所以将servlet包装成Context的StandardWrapper,是因为StandardWrapper是Tomcat的一部分,而servlet是独立的web开发标准,不应该强耦合
9.3 创建servlet
Tomcat启动的时候读取globalWebXml,并启动org.apache.servlets.DefaultServlet和org.apache.jasper.servelt.JspServlet。他们的load-on-map分别是1和3故会实例化Context
9.4 servlet的体系结构
与servlet主动关联的是ServletConfig,ServletRequest,ServletResponse。
ServletRequest:http的请求
ServletResponse:servlet的响应
ServletConfig:Servlet的一些配置属性
ServletContext:由于Servlet是“握手型交互模式”,即两个模块交换数据需要一定交易场景,交易场景就有ServletContext描述,配置信息就由ServletConfig描述。
9.5 Servlet如何工作
一个请求发送过来首先经过org.apache.tomcat.util.http.mapper(该对象保存了Tomcat Container中所有子容器的信息,通过观察者模式实现的)
9.6 Servlet中的Listener
是基于观察者模式设计的,
Init()初始化接口
doFilter()每个用户请求进来是这个方法都会被调用
Destory()对象销毁是这个方法被调用
9.7url-pattern
匹配一次请求是否会执行这个Servlet或者Filter