Tomcat启动时加载数据到缓存--web.xml里listener的加载顺序,优先初始化Spring IOC容器

本文介绍如何在Tomcat服务器启动时通过自定义缓存监听器加载数据到缓存,并确保其依赖于Spring的IOC容器。通过重写ContextLoaderListener的contextInitialized方法,实现了Spring与自定义缓存监听器的有序初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近用到在Tomcat服务器启动时自动加载数据到缓存,这就需要创建一个自定义的缓存监听器并实现ServletContextListener接口,并且在此自定义监听器中需要用到Spring的依赖注入功能.在web.xml文件中监听器配置如下:

xml代码:

<listener>  
   <listener-class> 
        org.springframework.web.context.ContextLoaderListener  
   </listener-class>  
</listener>  
<listener>  
   <listener-class>
        com.wsjiang.test.listener.CacheListener  
   </listener-class>  
</listener>

上面的配置细细大意为,先配置spring监听器,启动spring,再配置一个缓存监听器,我希望他们是顺序执行的,因为在缓存监听器中需要 spring注入其他对象的实例,我期望在服务器加载缓存监听器前加载Spring的监听器,将其优先实例化。但是实际运行发现他们并不是按照配置的顺序 加载的。
  对上面的问题我查询了很多资料,找到了一种解决方案,希望能帮助遇到同类问题的朋友。
  思路就是,既然listener的顺序是不固定的,那么我们可以整合两个listener到一个类中,这样就可以让初始化的顺序固定了。我就重写了 org.springframework.web.context.ContextLoaderListener这个类的 contextInitialized方法.大致代码如下:

Java代码:

public class ContextLoaderListenerOverWrite extends ContextLoaderListener {  
    private IStationService stationService;  
    private IOSCache osCache;  
    @Override  
    /** 
     * @description 重写ContextLoaderListener的contextInitialized方法 
     */  
    public void contextInitialized(ServletContextEvent event) {  
        super.contextInitialized(event);  
        ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());  
        //获取bean  
        stationService = (IStationService) applicationContext.getBean("stationService");   
        osCache = (IOSCache) applicationContext.getBean("osCache");  
        /* 
         具体地业务代码 
         */  
    }  
}

web.xml的配置就由两个listener变为一个:

Xml代码:

<listener>  
    <listener-class>  
                 com.wsjiang.test.listener.ContextLoaderListenerOverWrite  
        </listener-class>  
</listener> 
这样就能保证Spring的IOC容器先于自定义的缓存监听器初始化,在缓存监听器加载的时候就能使用依赖注入的实例.

参考文章:http://fengbin2005.iteye.com/blog/2065336

<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name></display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:applicationContext*.xml classpath*:*Context.xml </param-value> </context-param> <context-param> <param-name>webAppRootKey</param-name> <param-value>rms.root</param-value> </context-param> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60</param-value> </context-param> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <listener> <listener-class>com.hg.filter.UrlAuthListen</listener-class> </listener> <listener> <listener-class>com.hg.filter.WebConfigListener</listener-class> </listener> <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter </filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>XssFilter</filter-name> <filter-class>com.hg.aop.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- dwr 配置 --> <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>crossDomainSessionSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <description>How quickly do scriptSessions timeout?</description> <param-name>scriptSessionTimeout</param-name> <param-value>1800000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener</listener-class> </listener> <!-- dwr 配置 --> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>具体解释一下web.xml的配置
最新发布
07-08
<think>好的,我现在需要解释用户提供的web.xml配置文件的具体内容。首先,我需要回忆一下web.xml的基本结构和各个元素的作用。用户提供的这个配置文件是一个标准的Java Web应用的部署描述符,版本是3.0,所以可能使用了一些Servlet 3.0的特性,但这主要是传统的配置方式。 首先看根元素<web-app>,它的命名空间和schemaLocation指定了使用的规范版本,这是3.0。接下来是<display-name>,这为空,可能是应用的显示名称。 接下来是多个<context-param>元素,这些是上下文参数,由Servlet容器(如Tomcat加载,供应用中的组件使用。第一个context-param的param-name是contextConfigLocation,param-value指定了Spring应用上下文的配置文件位置,这包括classpath下所有以applicationContext开头的XML文件和所有以Context结尾的XML文件,这样SpringContextLoaderListener加载这些配置来初始化ApplicationContext。 第二个context-param是webAppRootKey,设置为rms.root,这通常用于将Web应用的根路径(如Tomcatwebapps下的应用目录)设置为一个系统属性,方便其他组件(如日志配置)引用,例如log4j中可能用${rms.root}获取路径。 第三个和第四个context-param是log4j的配置,log4jConfigLocation指定log4j的配置文件路径在/WEB-INF/classes/log4j.properties,log4jRefreshInterval设置为60秒,即每隔60秒自动刷新log4j的配置,这样修改日志配置后不需要重启应用。 接下来是<listener>元素,定义了多个监听器。第一个是Log4jConfigListener,用于初始化log4j的配置,读取前面的log4j相关context-param。第二个是ContextLoaderListener,这是Spring的监听器,负责根据contextConfigLocation加载Spring的应用上下文,是Spring Web应用的核心监听器。后面两个监听器是自定义的,com.hg.filter.UrlAuthListen和WebConfigListener,可能用于URL权限验证和Web配置初始化。 然后是<filter>和<filter-mapping>配置。第一个filter是openSessionInViewFilter,类是Spring ORM Hibernate4的OpenSessionInViewFilter,用于解决Hibernate的“延迟加载在视图层失败”的问题。设置singleSession为true,表示每个请求使用一个Hibernate Session,通常在Web应用中用于在请求处理期间保持Session打开,直到视图渲染完成。 第二个filter是struts2的StrutsPrepareAndExecuteFilter,这是Struts 2的核心过滤器,负责处理所有请求,解析Action、执行拦截器链等,url-pattern为/*,表示所有请求都由Struts处理。 第三个filter是自定义的XssFilter(跨站脚本攻击过滤器),类是com.hg.aop.XssFilter,用于过滤请求中的XSS攻击,例如转义特殊字符,保护应用安全,同样映射到所有URL。 接下来是dwr(Direct Web Remoting)的配置,这是一个用于Java和JavaScript互操作的库。定义了一个名为dwr-invoker的Servlet,类是DwrServlet,配置了debug模式(允许调试)、activeReverseAjaxEnabled(启用反向Ajax,服务器向客户端推送)、crossDomainSessionSecurity(跨域会话安全,这设为false)、scriptSessionTimeout(脚本会话超时时间,1800000毫秒即30分钟)。load-on-startup设置为1,表示Servlet容器启动时立即加载这个Servlet。servlet-mapping将/dwr/*的请求映射到这个Servlet,处理DWR相关的请求。同时还有一个EfficientShutdownServletContextAttributeListener监听器,用于DWR的高效关闭,释放资源。 最后是<welcome-file-list>,指定默认的欢迎文件为index.jsp,当访问应用根路径时,会默认访问这个文件。 现在需要检查是否有遗漏的部分,比如各个元素的作用是否解释清楚,特别是监听器、过滤器、Servlet的配置目的。另外,需要注意一些细节,比如openSessionInViewFilter的作用,Struts2过滤器的职责,XssFilter的用途,DWR的配置参数含义等。确保每个配置项的解释准确,并且符合Web应用开发的常见实践。 </think> 这个`web.xml`是Java Web应用的部署描述符(Servlet 3.0版本),定义了应用的初始化参数、监听器、过滤器、Servlet及欢迎文件等配置。以下是各部分的详细解释: ### **1. 根元素与基本信息** ```xml <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> ``` - 声明使用Servlet 3.0规范,`xsi:schemaLocation`指定了XML模式文件的位置,用于验证配置格式。 ### **2. 上下文参数(`<context-param>`)** 上下文参数由Servlet容器(如Tomcat加载,供全局组件(如监听器、过滤器)使用。 #### (1)`contextConfigLocation` ```xml <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath*:applicationContext*.xml classpath*:*Context.xml </param-value> </context-param> ``` - **作用**:指定Spring应用上下文(`ApplicationContext`)的配置文件路径。 - **含义**:加载类路径(`classpath`)下所有以`applicationContext`开头或包含`Context`的XML文件(如`applicationContext-datasource.xml`、`springContext.xml`),用于初始化Spring IoC容器。 #### (2)`webAppRootKey` ```xml <context-param> <param-name>webAppRootKey</param-name> <param-value>rms.root</param-value> </context-param> ``` - **作用**:将Web应用的根路径(如`/usr/local/tomcat/webapps/应用名/`)设置为系统属性,供其他组件(如日志框架)引用。 - **示例**:在`log4j.properties`中可通过`${rms.root}`获取应用根路径。 #### (3)`log4jConfigLocation` 与 `log4jRefreshInterval` ```xml <context-param> <param-name>log4jConfigLocation</param-name> <param-value>/WEB-INF/classes/log4j.properties</param-value> </context-param> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60</param-value> </context-param> ``` - **作用**:配置Log4j日志框架的属性文件路径及自动刷新间隔。 - **含义**: - `log4jConfigLocation`:指定Log4j配置文件路径为`/WEB-INF/classes/log4j.properties`(通常存放类路径下的资源)。 - `log4jRefreshInterval`:设置日志配置的自动刷新间隔为60秒,修改`log4j.properties`后无需重启应用即可生效。 ### **3. 监听器(`<listener>`)** 监听器用于监听Servlet容器的生命周期事件(如应用启动/销毁)。 #### (1)`Log4jConfigListener` ```xml <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> ``` - **作用**:初始化Log4j日志框架,读取前面定义的`log4jConfigLocation`和`log4jRefreshInterval`参数,完成日志配置的加载和定时刷新。 #### (2)`ContextLoaderListener` ```xml <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> ``` - **作用**:Spring的核心监听器,负责根据`contextConfigLocation`参数加载Spring应用上下文(`ApplicationContext`),是SpringWeb容器集成的关键。 #### (3)自定义监听器(`UrlAuthListen`、`WebConfigListener`) ```xml <listener> <listener-class>com.hg.filter.UrlAuthListen</listener-class> </listener> <listener> <listener-class>com.hg.filter.WebConfigListener</listener-class> </listener> ``` - **作用**:用户自定义的监听器,可能用于: - `UrlAuthListen`:URL权限校验(如应用启动时加载权限规则)。 - `WebConfigListener`:Web应用初始化配置(如加载全局参数、缓存初始化)。 #### (4)DWR的`EfficientShutdownServletContextAttributeListener` ```xml <listener> <listener-class>org.directwebremoting.servlet.EfficientShutdownServletContextAttributeListener</listener-class> </listener> ``` - **作用**:DWR(Direct Web Remoting)库的监听器,用于在应用销毁时高效释放DWR相关资源(如反向Ajax连接)。 ### **4. 过滤器(`<filter>`与`<filter-mapping>`)** 过滤器用于拦截请求/响应,执行预处理或后处理逻辑。 #### (1)`OpenSessionInViewFilter`(Hibernate会话管理) ```xml <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class> <init-param> <param-name>singleSession</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - **作用**:解决Hibernate的“延迟加载在视图层失败”问题(`LazyInitializationException`)。 - **原理**:在HTTP请求开始时打开Hibernate `Session`,请求结束时关闭,确保视图渲染(如JSP)时仍可访问延迟加载的关联对象。 - `singleSession=true`:每个请求使用一个共享的`Session`(默认行为)。 #### (2)Struts 2核心过滤器(`StrutsPrepareAndExecuteFilter`) ```xml <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - **作用**:Struts 2框架的核心过滤器,负责处理所有HTTP请求,完成以下任务: - 解析请求URL,匹配对应的Action。 - 执行拦截器链(如参数绑定、验证)。 - 调用Action的业务逻辑。 - 转发到结果视图(如JSP、Freemarker)。 - `url-pattern=/*`:所有请求(包括静态资源)都由Struts处理(需注意静态资源过滤配置,避免被错误拦截)。 #### (3)自定义XSS过滤器(`XssFilter`) ```xml <filter> <filter-name>XssFilter</filter-name> <filter-class>com.hg.aop.XssFilter</filter-class> </filter> <filter-mapping> <filter-name>XssFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> ``` - **作用**:防御跨站脚本攻击(XSS),对请求参数、请求体中的恶意脚本(如`<script>`标签)进行转义或过滤。 - **实现逻辑**:通常通过重写`HttpServletRequest`的`getParameter()`等方法,对输入内容进行安全处理。 ### **5. DWR Servlet配置** DWR(Direct Web Remoting)是一个允许Java代码在浏览器端通过JavaScript调用的库,用于简化前后端交互。 #### (1)`dwr-invoker` Servlet定义 ```xml <servlet> <servlet-name>dwr-invoker</servlet-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>crossDomainSessionSecurity</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>scriptSessionTimeout</param-name> <param-value>1800000</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dwr-invoker</servlet-name> <url-pattern>/dwr/*</url-pattern> </servlet-mapping> ``` - **核心参数解释**: - `debug=true`:启用DWR调试模式(开发阶段使用,生产环境应关闭)。 - `activeReverseAjaxEnabled=true`:启用反向Ajax(服务器主动向客户端推送消息)。 - `crossDomainSessionSecurity=false`:关闭跨域会话安全校验(允许跨域请求)。 - `scriptSessionTimeout=1800000`:设置DWR脚本会话的超时时间为30分钟(单位:毫秒)。 - `load-on-startup=1`:Servlet容器启动时立即加载此Servlet(优先级较高)。 - **映射路径**:所有`/dwr/*`的请求由`DwrServlet`处理(如`/dwr/engine.js`用于加载DWR客户端脚本)。 ### **6. 欢迎文件列表(`<welcome-file-list>`)** ```xml <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> ``` - **作用**:当访问应用根路径(如`http://localhost:8080/应用名/`)时,默认跳转的页面为`index.jsp`。 ### 总结 此`web.xml`整合了Spring、Struts 2、Hibernate、Log4j、DWR等框架,定义了应用的初始化参数、监听器(用于框架启动和资源管理)、过滤器(用于请求处理和安全防护)、Servlet(用于DWR交互)及默认访问页面,是传统Java EE Web应用的典型配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值