首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

Tomcat7中web应用加载原理(3)Listener、Filter、Servlet的加载和调用

2013-10-12 
Tomcat7中web应用加载原理(三)Listener、Filter、Servlet的加载和调用前一篇文章分析到了org.apache.catalin

Tomcat7中web应用加载原理(三)Listener、Filter、Servlet的加载和调用

前一篇文章分析到了org.apache.catalina.deploy.WebXml类的configureContext方法,可以看到在这个方法中通过各种setXXX、addXXX方法的调用,使得每个应用中的web.xml文件的解析后将应用内部的表示Servlet、Listener、Filter的配置信息与表示一个web应用的Context对象关联起来。

这里列出configureContext方法中与Servlet、Listener、Filter的配置信息设置相关的调用代码:

这303行可以讲的东西有很多,为了不偏离本文主题只抽出与现在要讨论的问题相关的代码来分析。

?

第125行会发布一个CONFIGURE_START_EVENT事件,按前一篇博文所述,这里即会触发对web.xml的解析。第205、206行设置实例管理器为DefaultInstanceManager(这个类在后面谈实例构造时会用到)。第237行会调用listenerStart方法,第255行调用了filterStart方法,第263行调用了loadOnStartup方法,这三处调用即触发Listener、Filter、Servlet真正对象的构造,下面逐个分析这些方法。

?

listenerStart方法的完整代码较长,这里仅列出与Listenner对象构造相关的代码:

先从Context对象中取出实例变量applicationListeners(该变量的值在web.xml解析时设置),第12行通过调用instanceManager.newInstance(listener.getClassName()),前面在看StandardContext的startInternal方法第205行时看到instanceManager被设置为DefaultInstanceManager对象,所以这里实际会执行DefaultInstanceManager类的newInstance方法:

这段代码看起来很简单,取出web.xml解析时读到的filter配置信息,在第17行调用ApplicationFilterConfig了构造方法:

在web应用启动时将会加载配置了load-on-startup属性的Servlet。第24行,调用了StandardWrapper类的load方法:

在第2行loadServlet方法中与上面的Listener和Filter对象构造一样调用instanceManager.newInstance来构造Servlet对象,与Filter类似在第5行调用Servlet的init方法。

当然,这种加载只是针对配置了load-on-startup属性的Servlet而言,其它一般Servlet的加载和初始化会推迟到真正请求访问web应用而第一次调用该Servlet时,下面会看到这种情况下代码分析。

?

以上分析的web应用启动后这些对象的加载情况,接下来分析一下一次请求访问时,相关的Filter、Servlet对象的调用。

?

在本博前面的《Tomcat7中一次请求处理的前世今生》系列文章中曾经分析了一次请求如何与容器中的Engine、Host、Context、Wrapper各级组件匹配,并在这些容器组件内部的管道中流转的。在该系列第四篇文章最后提到,一次请求最终会执行与它最适配的一个StandardWrapper的基础阀org.apache.catalina.core.StandardWrapperValve的invoke方法。当时限于篇幅没继续往下分析,这里接着这段来看看请求的流转。看下invoke方法的代码:

FilterChain.doFilter(request, response);

这样就又回到了filterChain的doFilter方法,形成了一个递归调用。要注意的是,filterChain对象内部的pos是不断加的,所以假如过滤器链中的各个Filter的doFilter方法都执行完之后将会执行到第63行,在接下来的第92行、第95行即调用Servlet的service方法。

热点排行