转载于点击打开链接
有时候面试时会被问tomcat启动时web.xml中节点(类似listener,filter等)被加载的顺序,死记硬背那多没品,正好手里有tomcat7的源码,找了点时间翻了翻。
让我们先来喵一眼tomcat的架构,大致了解下tomcat启动的顺序,那我们目前关心的仅仅是web.xml中的加载顺序,按照架构来讲肯定是在Context中,架构如下图:
那我们就来到Context中寻找线索,按照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 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
另外赠送一枚彩蛋,也就是load on startup中的启动顺序是按照配置参数从小到大加载实例化的(小于0的忽略),
源代码中是用一个TreeMap,其中键为Integer,那么就是按照配置参数默认从小到大排列启动。