详解web.xml中元素的加载顺序
一、背景
最近在项目中遇到了启动时出现加载service注解注入失败的问题,后来经过不懈努力发现了是因为web.xml配置文件中的元素加载顺序导致的,那么就抽空研究了以下tomcat在启动时web.xml文件中元素的加载顺序,现在和大家分享。
二、问题剖析和研究结果
遇到这种问题的时候,一般看源码是最直接和最权威的获取答案的方式,根据tomcat架构设计Context的实现类是StandardContext,全称org.apache.catalina.core.StandardContext。看到其实现Lifecycle接口,我们在StandardContext中找到startInternal方法,下面给出我把暂时无用的代码去掉后的注释版源码:
/**
* Start this component and implement the requirements
* of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
*
* @exception LifecycleException if this component detects a fatal error
* that prevents this component from being used
*/
@Override
protectedsynchronized void startInternal() throwsLifecycleException {
//设置webappLoader 代码省略 // Standard container startup 代码省略 try{ // Set up the context init params
//初始化context-param节点数据
mergeParameters(); // Configure and call application event listeners
//配置和调用应用程序事件listeners
if(ok) {
if(!listenerStart()) {
log.error("Error listenerStart");
ok = false;
}
} // Configure and call application filters
//配置和调用应用程序filters
if(ok) {
if(!filterStart()) {
log.error("Error filterStart");
ok = false;
}
} // Load and initialize all "load on startup" servlets
//加载和初始化配置在load on startup的servlets
if(ok) {
loadOnStartup(findChildren());
} // Start ContainerBackgroundProcessor thread
super.threadStart();
}finally{
// Unbinding thread
unbindThread(oldCCL);
} }
那我们接着归纳和整理一下代码:
1.首先初始化context-param节点
2.接着配置和调用listeners 并开始监听
3.然后配置和调用filters filters开始起作用
4.最后加载和初始化配置在load on startup的servlets
即元素加载顺序为:
context-param --> listeners --> filters --> servlets
注意:
1.该加载顺序并不会受元素在web.xml文件中的位置的影响。
2.但对于某类配置节而言,与它们出现的顺序是有关的。以 filter 为例,web.xml 中当然可以定义多个 filter,与 filter 相关的一个配置节是 filter-mapping,这里一定要注意,对于拥有相同 filter-name 的 filter 和 filter-mapping 配置节而言,filter-mapping 必须出现在 filter 之后,否则当解析到 filter-mapping 时,它所对应的 filter-name 还未定义。web 容器启动时初始化每个 filter 时,是按照 filter 配置节出现的顺序来初始化的,当请求资源匹配多个 filter-mapping 时,filter 拦截资源是按照 filter-mapping 配置节出现的顺序来依次调用 doFilter() 方法的。
接着让我们来回忆一下web项目的启动顺序
1.web容器读取web.xml配置文件,并首先读取<context-param>和<listener>两个结点。
2.容器创建一个ServletContext(servlet上下文),该web项目的所有部分都将共享这个上下文。
3.容器将<context-param>转换为键值对,并交给servletContext。
4.容器按照load on startup中的启动顺序创建<listener>中的类实例,创建监听器。
关于load on startup
load-on-startup 元素在web应用启动的时候指定了servlet被加载的顺序,它的值必须是一个整数。
如果它的值是一个负整数或是这个元素不存在,那么容器会在该servlet被调用的时候,加载这个servlet 。
如果值是正整数或零,容器在配置的时候就加载并初始化这个servlet,容器必须保证值小的先被加载。如果值相等,容器可以自动选择先加载谁。
正数的值越小,启动该servlet的优先级越高。
三、总结
通过研究源码我们明白了web.xml中各个元素的加载顺序,再遇到这种问题,我们就可以很快的定位出问题所在了。由此也发现和体会到了研究源码是一种很好的习惯也是解决问题不可缺少的方式。
详解web.xml中元素的加载顺序的更多相关文章
- 【转】详解web.xml中元素的加载顺序
顺序为: context-param --> listeners --> filters --> servlets(如DispatcherServlet等) 详见<https: ...
- 服务器启动时Webapp的web.xml中配置的加载顺序
一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...
- 服务器启动时Webapp的web.xml中配置的加载顺序(转载)
一 1.启动一个WEB项目的时候,WEB容器会去读取它的配置文件web.xml,读取<listener>和<context-param>两个结点. 2.紧急着,容创建一个Ser ...
- web.xml的配置及加载顺序
一web.xml加载过程(步骤): 1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> ...
- web项目中配置文件的加载顺序
当一个项目启动时,首先是web.xml: 这里面的配置: 为什么要在web.xml中配置struts的过滤器? 因为一个web项目运行的时需要加载的,或者默认的部分配置都会在web.xml中配置,中间 ...
- C#开发BIMFACE系列50 Web网页中使用jQuery加载模型与图纸
BIMFACE二次开发系列目录 [已更新最新开发文章,点击查看详细] 在前一篇博客<C#开发BIMFACE系列49 Web网页集成BIMFACE应用的技术方案>中介绍了目前市场主流 ...
- 如果你还不知道如何控制springboot中bean的加载顺序,那你一定要看此篇
1.为什么需要控制加载顺序 springboot遵从约定大于配置的原则,极大程度的解决了配置繁琐的问题.在此基础上,又提供了spi机制,用spring.factories可以完成一个小组件的自动装配功 ...
- Tomcat启动过程原理详解 -- 非常的报错:涉及了2个web.xml等文件的加载流程
Tomcat启动过程原理详解 发表于: Tomcat, Web Server, 旧文存档 | 作者: 谋万世全局者 标签: Tomcat,原理,启动过程,详解 基于Java的Web 应用程序是 ser ...
- web应用配置文件详解(web.xml)
转载链接地址:http://blog.csdn.net/guihaijinfen/article/details/8363839 <?xml version="1.0" en ...
随机推荐
- 微信电脑版即将到来了 安装QQ浏览器微信版体验吧
之前说过在手机上微信打字慢,tx最终还是想开了,最近TX邀请测试微信电脑版,想要尝鲜的朋友可以去exp.qq.com申请QQ浏览器微信版体验,不过体验将要结束了,相信正式版很快就要出来了.[微信网页版 ...
- Linux之服务器时间同步
Linux时间同步(把nameNode1作为时间同步服务器) 设置时区 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 联网情况:ntpdate ...
- Mac Pro 开机自启动 PHP-FPM,Nginx,MySql 等软件
在Mac下安装好了PHP开发环境(PHP-FPM,Nginx,MySql), 想设置成开机自启动,原来以为和一般的Linux系统一样,也是在rc.d这样目录放置启动脚本.在网上查了一些资料,发现苹果应 ...
- Code First02---CodeFirst配置实体与数据库映射的两种方式
Code First有两种配置数据库映射的方式,一种是使用数据属性DataAnnotation,另一种是Fluent API. 这两种方式分别是什么呢?下面进行一一解释: DataAnnotation ...
- JDIC 访问Web时NullPointerException
Exception in thread "EventThread" java.lang.NullPointerException at org.jdeskto ...
- C语言 homework(4)
#include <stdio.h> int main(){ ; i=; ) { sum+=i; i++; } printf("sum=%d\n",sum); ; } ...
- PYTHON seek()tell()语句
print(f.tell()) # 显示当前位置 f.seek(0) #回到某一起点
- linux kernel 杂谈
首先介绍一下背景吧,工作三个星期了.复习了一波u-boot,跟了一下事件上报,搞了下平台设备,扣了一个内存检查代码. 想想生活是不是有点无聊.对啊,真的很无聊!!!! 无聊也没有办法啊,所以找点方法去 ...
- Codeforces Gym 101138 G. LCM-er
Description 在 \([a,b]\) 之间选择 \(n\) 个数 (可以重复) ,使这 \(n\) 个数的最小公倍数能被 \(x\) 整除,对 \(10^9+7\) 取膜. \(1\leqs ...
- BZOJ 1511: [POI2006]OKR-Periods of Words
Description 求一个最长周期. Sol KMP. 一个点的最短周期就是 \(i-next[i]\) 此外 \(i-next[next[i]],i-next[next[next[i]]]\) ...