ContextLoaderListener和IntrospectorCleanupListener

你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

ContextLoaderListener

ContextLoaderListener作用

ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

ContextLoaderListener文档说明

第一段说明ContextLoader可以由 ContextLoaderListener和ContextLoaderServlet生成。如果查看ContextLoaderServlet的API,可以看到它也关联了ContextLoader这个类而且它实现了HttpServlet这个接口。

第二段,ContextLoader创建的是 XmlWebApplicationContext这样一个类,它实现的接口是WebApplicationContext->ConfigurableWebApplicationContext->ApplicationContext->BeanFactory这样一来spring中的所有bean都由这个类来创建

ContextLoaderListener配置

在web.xml中加入代码:

<!-- 添加ContextLoaderListener监听器相关代码 -->
<listener>
	<!-- ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。 -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

IntrospectorCleanupListener

IntrospectorCleanupListener作用

IntrospectorCleanupListener实现了ServletContextListener接口,也就是说,
在web容器初始化(准确的说是在filters或servlets初始化之前)的时候会执行contextInitialized方法,
在ServletContext销毁(准确的说是在filters和servlets销毁之后)的时候会执行contextDestroyed方法。
销毁ServletContext的时候调用了Introspector.flushCaches方法,清空对应缓存.

	注意:在使用Spring本身的时候并不需要使用此监听器,因为Spring自己的内部机制会立即清空对应的缓存。
	虽然,Spring本身不存在这样的问题,但是如果和其它框架结合使用,而其它框架有这个问题,如Struts、Quartz等,
	那就需要配置这个监听器,在销毁ServletContext的时候清空对应缓存。

IntrospectorCleanupListener文档说明

通过查看Introspector.getBeanInfo方法的源码会发现,Introspector在构建一个BeanInfo对象的时候,会将构建的BeanInfo对象和原类缓存到一个Map中,源码如下。
在这里插入图片描述
通过上的代码可以得出,Introspector间接持有了BeanInfo的强引用。如果使用Introspector操作了很多类,那么Introspector将间接持有这些BeanInfo的强引用。在发生垃圾收集的时候,检测到这些BeanInfo存在引用链,则这些类和对应的类加载器将不会被垃圾收集器回收,进而导致内存泄漏。所以,为了解决这个问题,在使用Introspector操作完成后,调用Introspector类的flushCaches方法清除缓存。
在这里插入图片描述
通过上面的代码会发现,清除的时候是清空了整个缓存,因为没有很好的办法来确定每个缓存是属于哪个应用的,所以清除的时候会清除所有应用的缓存。

IntrospectorCleanupListener配置

在web.xml中加入代码:

<!-- 添加ContextLoaderListener监听器相关代码 -->
<listener>
	 <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>

说明

IntrospectorCleanupListener在使用时会配合ContextLoaderListener,一般会把web.xml中将IntrospectorCleanupListener配置成非第一个listener。
在这里插入图片描述
其实,看过源码的都知道,官方的表述是必须将此监听器配置成web.xml中的第一个listener,才能在合适的时间发挥最有效的作用。

原因其实很简单,在Servlet3.0规范之前,监听器的调用是随机的,而从Servlet3.0开始,监听器的调用顺序是根据其在web.xml中配置的顺序,并且实现ServletContextListener的监听器,contextInitialized方法调用顺序是按照在web.xml中配置的顺序正序依次执行,而contextDestroyed方法的调用顺序是按照在web.xml中配置的顺序逆序依次执行。所以,如果IntrospectorCleanupListener被配置成了第一个listener,那么它的contextDestroyed方法将最后一个执行,将发挥最有效的清除作用;而如果不是,那么可能会残留未被清除的缓存。

本文章借鉴JavaQ,借鉴文章链接:https://www.jianshu.com/p/b167716f9c0c

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值