您的位置:首页 > 其它

Servlet工作原理摘要

2016-12-28 16:00 253 查看

Servlet容器是如何工作的

Context容器直接管理Servlet的包装类Wrapper

Tomcat public addWebapp() {创建Context(StandardContext),ConextConfig配置}

ContextConfig:负责完成整个Web应用的配置文件解析工作

ContextConfig的init:{

创建用于解析XML的contextRegister对象。
读取默认的context.xml,如果存在则解析它。
读取默认的Host配置文件,如果存在则解析它。
读取默认的Context自身的配置文件,如果存在则解析它。
设置Context的DocBase。//应用实际的物理路径


}

Context容器:startInternal:

{

创建读取资源的对象
创建ClassLoader对象
设置应用的工作目录
启动相关的辅助类
修改启动状态,通知感兴趣的观察者
子容器初始化
获取Servlet并设置必要的参数
初始化Servlet(load on startup)


}

Servlet容器在web工程中是如何启动和如何解析web.xml

Web应用的初始化开始于ContextConfig.configureStart方法中实现的。主要是解析web.xml文件,web应用的关键信息,web应用的入口。

Tomcat需要globalWebXml和hostWebXml

查找:C:\apache-tomcat-7.0.56\conf\web.xml

寻找应用程序的web.xml文件,如/WEB-INF/web.xml,WebXml对象解析。

启动,

设置JSP

设置加载时启动LoadOnStartup

判断Servlet是否Enable

初始化initParameter

设置安全参考信息

设置wrapper的Class类

设置Servlet是否允许的文件上传的,MultiPartFile…之类的。

设置是否支持异步

最后添加到context托管。

for(ServletDef servlet:servlets.values){
Wrapper wrapper =context.createWrapper();
String jspFile=servlet.getJspFile();
wrapper.setJspFile(jspFile);
wrapper.setName(servlet.getServletName);
wrapper.setServletClass(servlet.getServletClass());

.....
context.addChild(wrapper);
}


这里:生成的Servlet的包装类Wrapper,而不是具体的Servlet对象,原因是Wrapper类是Tomcat容器的一部分,具有容器的特性,而Servlet是web开发的标准,不作耦合。

一个Web应用对应于一个Context容器,所以真正管理Servlet的是Context容器,容器的配置属性由web.xml设置的。

生成Servlet对象

Wrapper.loadServlet—>获取ServletClass.class—>InstanceManager生成ServletClass.class对应的对象。

**StandardContext.lifecycleEvent()–>ContextConfig.configureStart()—>webConfig—>new WebXml–>parseWebXml(globalWebXml,hostWebXml)—>configureContext()–>set(属性全设置到容器中)—>Wrapper.createWrapper()—>set(Wrapper的各种属性,包括ServletClass.class)—>

Context.addChild(wrapper)—>设置其他属性如(servletMapping)—>容器执行StartInternal==>加载资源,启动其他组件如Logger,realm==>loadOnStartup==>load。

StandardWrapper.loadServlet()–>InstanceManager.newInstance()–>initServlet()–>init(this.facade)**

this.facade是StandardWrapperFacade类实例,该类实现ServletConfig接口,并持有ServletConfig的一个实现类StandardWrapper的引用,并暴露出部分数据(足够生成Servlet)称为:门面设计模式。

用户请求是如何分配给指定Servlet的

Servlet 如何工作

http://hostname:port/contextpath/servletpath, hostname+port用于TCP连接。

org.apache.tomcat.util.http.mapper //完成根据URL选择服务器中哪种子容器来服务请求。这个类保存Tomcat中的Container所有子容器信息。在Request类进入Container容器之前,Mapper会根据Hostname和ContextPath,将hostname和context设置到Request类中的mappingData中,这样在还没有进入到Container之前就已经确定了要访问哪个容器。

为何mapper含有全部信息,原因是存在MapperListener,对容器进行监听,在容器发生变化的时候,Mapper对应的属性也会更改。

在Mapper.init过程中将host下面的子容器注册到Mapper中。

Filter如何工作

定义在web.xml的filter配置项中,和组合使用。除了Request和Response对象,还给了一个FilteChain对象,更灵活地控制跳转。

找了一个源码org\springframework\web\filter\CompositeFilter.java。然后找到doFilter方法

@Override
public void doFilter(final ServletRequest request, final ServletResponse response)
throws IOException, ServletException {

if (this.currentPosition == this.additionalFilters.size()) {
this.originalChain.doFilter(request, response);
}
else {
this.currentPosition++;
Filter nextFilter = this.additionalFilters.get(this.currentPosition - 1);
nextFilter.doFilter(request, response, this);
}
}


基本思想就是用一个position指针指向当前位置,如果filter没有到最后这接着往下执行,直到最后。

看了源码然后发现FilterChain链条的实现似曾相识,果不其然:

http://blog.csdn.net/Newpidian/article/details/53925448

这篇博客写的是实现链式AOP动态代理,实现起来的结果就像这样。

a.before()
b.before()
result=targetMethod.invokeSuper();
b.after()
a.after()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  servlet