ContextLoaderListener

Spring定义成:分层的J2EE应用框架

1、查看ContextLoaderListener源代码

发现它继承自ContextLoader,并且实现ServletContextListener接口。

ContextLoaderListener 源代码很简单,核心是实现了 ServletContextListener 的contextInitialized和contextDestroyed方法

我们看下类图结构,只列出一部分属性和方法:

因为 contextInitialized和contextDestroyed 方法分别调用了 ContextLoader里面的initWebApplicationContext和closeWebApplicationContext方法

所以核心最终还是 ContextLoader 实现了这个监听器,那这个监听器实现了什么功能呢,我们发现有两个重要属性

contextConfigLocation:即在web.xml里面指定的配置文件所在目录,如果不指定,Spring 会加载WEB_INF目录下,符合 *Context.xml 或 spring*.xml 规则的文件

currentContextPerThread:保存了当前WebApplicationContext

参考:https://blog.csdn.net/gzu_imis/article/details/18989679

参考:https://blog.csdn.net/ysughw/article/details/8992322


其实监听器的加载过程可以描述为:

先判WebApplicationContext是否已存在,不存在的话则初始化一个XmlWebApplicationContext(WebApplicationContext的子类),并把该实例put到 currentContextPerThread 中。而初始化 XmlWebApplicationContext 时,就跟我们使用 new ClassPathXmlApplicationContext(contextConfigLocation)一样

将我们配置的各种bean都添加到XmlWebApplicationContext中,所以我们知道 ApplicationContext 提供各种 getBean的方法。。。

并且可以发现 ContextLoader还提供了获取当前 WebApplicationContext的静态方法:之所以能获取,是因为initWebApplicationContext初始化方法把创建的XmlWebApplicationContext 塞到了 currentContextPerThread 中
注意:说了一堆,跟Spring MVC 不配置ContextLoaderListener有什么关系呢。。。
因为 ContextLoaderListener 本质上是创建了一个 WebApplicationContext ,所以你的项目里面,如果不使用 WebApplicationContext 就可以不配置该节点。

问题:

在Servlet中使用注解的方式引用Spring bean对象,会报空指针,因此可以在init()方法中通过。

原本spring管理的bean和servlet不在一个上下文环境中是无法相互注入的。

解决:

通过使用spring提供的支持可以将当前的servlet上下文环境添加到spring管理的上下文环境中。

 关键在于SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,getServletContext());

@Override
public void init() throws ServletException {  
SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this,getServletContext()); }

参考:https://blog.csdn.net/cc206476/article/details/78739137

原文地址:https://www.cnblogs.com/moonsoft/p/10143006.html