接上一篇:Listener(倾听者)

ContextLoaderListener是啥,是谁写的?

  • ContextLoaderListener是一个监听器
  • Spring编写并提供

我们搭建SSM框架时,需要做的仅仅是在web.xml中配置它,一般是这样:

img

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

img

先不看ContextLoader,我们发现ContextLoader实现了ServletContextListener(三大生命周期监听之一)。上一篇文章中,我画的图还不够严谨:

imgServletContextListener是个接口,具体的监听器应该是它的实现类对象

实际应该是这样:

img

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

img

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

img

也就是说Tomcat的ServletContext创建时,会调用ContextLoaderListener的contextInitialized(),这个方法内部的initWebApplicationContext()就是用来初始化Spring的IOC容器的。再强调一遍:

  • ServletContext对象是Tomcat的
  • ServletContextListener是Tomcat提供的接口
  • ContextLoaderListener是Spring写的,实现了ServletContextListener
  • Spring自己写的监听器,用来创建Spring IOC容器天经地义

img

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

img

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

img

还有两个小细节要和大家叨一叨。

  • 我们自己编写注册ContextLoaderListener的代码了吗?

上一篇文章我们自己调用registerListener()注册了监听器:

img

现在呢?

img

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

img

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

img

所以我们已经不需要显示注册监听器了,只要在web.xml中配置即可。我自学SSM时,就一直不明白,一行配置咋就注册了呢?啥叫注册?我当时不懂,不知道你们现在稍微懂一点没有。

  • 上一篇说Event对象其实就是被监听对象的包装,那么创建IOC时,要ServletContext对象作甚?

img

那是因为,最终IOC容器其实是存放在ServletContext对象(容器)中。所以我上面就说了,别以为只有Spring会搞对象容器,我Tomcat虽然是一只小猫,但是吞你Spring。

imgTomcat内部可以部署多个应用,每个应用内部可以使用Spring,说穿了Spring只是某个应用WEB-INF/lib下导入的几个jar包

下面简单过一遍源码。看的时候,告诉自己,你看到的所有代码都在ContextLoader中,以免自乱阵脚:

img

img

img

img

img

示意图

img

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

img

img