不知不觉,转行已经四年了,感谢当时的选择,开启了我的新的世界。如果没有当初的选择,可能现在在老家工地上搬砖。在这几年里,也渐渐从小白变成所谓中高级后端开发工程师。走过坑 ,趟过泥,写过屎山代码。言归正传,开始从入门到放弃的系列。
最近也在看tomcat源码,也在逐渐理解一个http请求的来龙去脉。现在不写这个,先写tomcat是如何初始化spring。
先理解一下spring ContextLoaderListener的作用
ContextLoaderListener的作用就是启动Web容器时,读取在contextConfigLocation中定义的xml文件,自动装配ApplicationContext的配置信息,并产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。
简单来说,就是上面这段配置为项目提供了spring支持,初始化了Ioc容器。
打开tomcat源码找到StandardContext.startInternal(),这个方法里面几千行代码,找到核心的监听部分的代码
//大约5063行,tomcat 版本不一样,可能位置不一样,关键字搜索到这一行即可
// Notify our interested LifecycleListeners
fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);
//进入方法之后完整代码,type=Lifecycle.CONFIGURE_START_EVENT data=null
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}
//看到这里估计有跟我有一样的疑问,lifecycleListeners 这个是从哪里来的,在下面类
//org.apache.catalina.util.LifecycleBase有如下代码
private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
// 但是这个集合的内容从哪里来呢?我也纳闷,搜了一下,网上大神有写在哪里
Digester digester = createStartDigester();
下面是 createStartDigester()部分代码
/**
* Create and configure the Digester we will be using for startup.
* @return the main digester to parse server.xml
*/
protected Digester createStartDigester() {
// Initialize the digester
Digester digester = new Digester();
digester.setValidating(false);
digester.setRulesValidation(true);
Map<Class<?>, List<String>> fakeAttributes = new HashMap<>();
List<String> objectAttrs = new ArrayList<>();
objectAttrs.add("className");
fakeAttributes.put(Object.class, objectAttrs);
// Ignore attribute added by Eclipse for its internal tracking
List<String> contextAttrs = new ArrayList<>();
contextAttrs.add("source");
fakeAttributes.put(StandardContext.class, contextAttrs);
digester.setFakeAttributes(fakeAttributes);
digester.setUseContextClassLoader(true);
********************