ContextLoaderListener解析
接上一篇:Listener(倾听者)
ContextLoaderListener是啥,是谁写的?
- ContextLoaderListener是一个监听器
- 由Spring编写并提供
我们搭建SSM框架时,需要做的仅仅是在web.xml中配置它,一般是这样:

我们常说的监听器一般是指具体的监听器对象,比如ContextLoaderListener。但这个对象怎么来的?它其实实现一个监听器接口。我们来看看ContextLoaderListener实现了哪个接口:

先不看ContextLoader,我们发现ContextLoader实现了ServletContextListener(三大生命周期监听之一)。上一篇文章中,我画的图还不够严谨:
ServletContextListener是个接口,具体的监听器应该是它的实现类对象
实际应该是这样:

所以,很明显Spring实现了Tomcat提供的ServletContextListener接口,写了一个监听器来监听项目启动。一旦项目启动,会触发ContextLoaderListener中的特定方法。

大致模拟一下ServletContext对象的创建,以及ServletContextListener的监听过程:

也就是说Tomcat的ServletContext创建时,会调用ContextLoaderListener的contextInitialized(),这个方法内部的initWebApplicationContext()就是用来初始化Spring的IOC容器的。再强调一遍:
- ServletContext对象是Tomcat的
- ServletContextListener是Tomcat提供的接口
- ContextLoaderListener是Spring写的,实现了ServletContextListener
- Spring自己写的监听器,用来创建Spring IOC容器天经地义

至于Spring怎么创建IOC容器的,大家自己可以翻源码。还记得web.xml中的那两处配置吗:

web.xml中配置了Spring配置文件的位置,那里边不是写了很多<bean/>啥的吗。读取xml配置文件反射创建对象加入IOC即可。

还有两个小细节要和大家叨一叨。
- 我们自己编写注册ContextLoaderListener的代码了吗?
上一篇文章我们自己调用registerListener()注册了监听器:

现在呢?

不用猜了,肯定有注册。不过不再是通过代码,而是xml配置。还是在web.xml中:

Tomcat会解析web.xml,反射创建ContextLoaderListener。不要以为只有Spring有对象容器,Tomcat也有好吧。

所以我们已经不需要显示注册监听器了,只要在web.xml中配置即可。我自学SSM时,就一直不明白,一行配置咋就注册了呢?啥叫注册?我当时不懂,不知道你们现在稍微懂一点没有。
- 上一篇说Event对象其实就是被监听对象的包装,那么创建IOC时,要ServletContext对象作甚?

那是因为,最终IOC容器其实是存放在ServletContext对象(容器)中。所以我上面就说了,别以为只有Spring会搞对象容器,我Tomcat虽然是一只小猫,但是吞你Spring。
Tomcat内部可以部署多个应用,每个应用内部可以使用Spring,说穿了Spring只是某个应用WEB-INF/lib下导入的几个jar包
下面简单过一遍源码。看的时候,告诉自己,你看到的所有代码都在ContextLoader中,以免自乱阵脚:





示意图

当然了,Spring也提供了工具类,方便从ServletContext中取出IOC容器:


本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。