ServletContextListener

Servlet应用程序需要放置到servlet容器中运行,那么应用程序需要与容器进行配合运行,就需要使用ServletContext 与 Web 容器通信。例如写日志,转发请求等。

每一个 Web 应用程序含有一个Context,也就是ServletContext,被Web应用内的各个程序共享。因为Context可以用来保存资源并且共享,所以我所知道的 ServletContext 的最大应用是Web缓存,用于存储我们应用程序常用的系统参数,数据等;

那么这个ServletContext如何被创建的呢? 如果ServletContext数据发生变更了怎么办呢?

ServletContextListener 此时就登场了!

ServletContextListener 是 ServletContext 的监听者, 他会监听ServletContext 发生的变化,如服务器启动时通过ServletContextListener  来创建初始化ServletContext ,服务器关闭时 ServletContext 将要被销毁也是通过ServletContextListener  对ServletContext以及存储的数据进行销毁。

具体如下:

  1. 服务器启动时,ServletContextListener 的 contextInitialized()方法被调用,所以在里面创建好缓存。可以从文件中或者从数据库中读取取缓存内容生成类,用 servletContext.setAttribute()方法将缓存类保存在 ServletContext 的实例中。

  2. 程序使用 ServletContext.getAttribute()读取缓存。如果是 JSP,使用application.getAttribute()。如果是 Servlet,使用 getServletContext().getAttribute()。如果缓存发生变化(如访问计数),你可以同时更改缓存和文件/数据库。或者你等变化积累到一定程序再保存,也可以在下一步保存。

  3. 服务器将要关闭时,ServletContextListener 的 contextDestroyed()方法被调用,所以在里面保存缓存的更改。将更改后的缓存保存回文件或者数据库,更新原来的内容。

Spring 中ServletContextListener是如何应用的?

我们知道spring项目在web容器中启动后,容器会首先读取web.xml配置文件,如下:

1、在web.xml配置监听器ContextLoaderListener

 <listener>  
 <listener-class>org.springframework.web.context.ContextLoaderListener
 </listener-class>
 </listener>

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

因此ContextLoaderListener帮助spring启动IoC容器,也就是ContextLoaderListener自动装配ApplicationContext的配置信息,并产生WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。

2、部署spring的xml文件

如何部署applicationContext的xml文件,如果在web.xml中不写任何参数配置信息,默认的路径是"/WEB-INF/applicationContext.xml,在WEB-INF目录下创建的xml文件的名称必须是applicationContext.xml。如果是要自定义文件名可以在web.xml里加入contextConfigLocation这个context参数:

<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>  
            /WEB-INF/classes/spring-*.xml 
        </param-value>  
    </context-param>

在<param-value> </param-value>里指定相应的xml文件名,如果有多个xml文件,可以写在一起并一“,”号分隔。上面的spring-*.xml采用通配符,比如这那个目录下有spring-mybatis-base.xml,spring-dao.xml等文件,都会一同被载入。

由此可见spring.xml的文件位置就可以有两种默认实现:

第一种:直接将之放到/WEB-INF下,之在web.xml中声明一个listener、

第二种:将之放到classpath下,但是此时要在web.xml中加入<context-param>,用它来指明你的spring.xml的位置以供web容器来加载。

以上加载spring的相关配置文件无非是将系统相关资源、数据、参数等加载到内存中,这也就是ServletContextListener完成的最终使命!

 

Spring Boot也用到了ContextLoaderListener?

目前SpringBoot已经成为了主流的项目架构,因此就会有人疑问,SpringBoot中会不会也用到了ContextLoaderListener,但是SpringBoot是通过main主函数来启动的,ContextLoaderListener不是需要在web.xml中配置的吗?springboot 哪来的web.xml?

那么我们来看看SpringBoot到底是怎么用到的ContextLoaderListener?

@SpringBootApplication
@EnableTransactionManagement
@ServletComponentScan
@MapperScan("com.xsxx.mapper")//配置mybatis包扫描

看到上面的代码是不是感觉知道了什么?

没错!就是注解,spring boot之所以强大,我个人认为,绝对有注解的功劳啊!

在Springboot web 应用启动代码中添加@ComponentScan注解,使我们的Springboot应用在启动时能扫描到该Listener.

运行项目,我们可以springboot的启动log看到如下log信息,即表明我们的ServletContextListener注册成功。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章