Spring框架中context-param与servlet中init-param的contextConfigLocation的区别

本文解析了Spring框架中定时任务的触发机制,特别是在spring-servlet.xml配置文件中的定时任务为何需要通过页面刷新来激活。文章详细阐述了两种配置方式的区别,并提供了解决方案。

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

积累,小白也可成为大神

最近在使用spring这一个框架做定时任务的时候,发现一个问题。当我们不在浏览器中调用一下我们的接口,是不会自动运行定时文件的,这个原因是什么呢?刚开始的时候,使我费解了很长事件,不知道问题出现再哪里。但是当冷静下来思考一下的时候,发现了问题出现再servlet中。接着,对它进行分析一下。

在springmvc这个框架中,一般spring默认存在两个配置文件,一个是applicationContext.xml,另一个是spring-servlet.xml。一般情况下,我们会把注解中的自动加载,定时器的自动加载等内容写在spring-servlet.xml。然后把spring-servlet.xml,放在web.xml文件下的servlet中进行初始化。例如:

<servlet>
        <servlet-name>spring</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
    </servlet>

而将applicationContext.xml配置成全局的形式,例如:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml,
            classpath:spring-servlet.xml
        </param-value>
</context-param>

对比一下,就会发现问题所在。spring-servlet.xml因为被配置在servlet的初始化过程中,所以如果不初始化servlet,那么spring-servlet.xml是不会被发现的。如果我们将定时器的注解加载过程放在spring-servlet.xml中,如果不进行页面的刷新,是不会经过DispatcherServlet这个跳转器的,所以也就不会加载spring-servlet.xml文件,所以定时任务可能就不会被触发。如果经过了这个DispatcherServlet这个跳转器,即被初始化。所以定时任务才会被执行。
而如果将注解的自动加载内容,例如:

<context:component-scan base-package="control"/><mvc:annotation-driven />

放在了applicationContext.xml中。因为当服务器运行起来之后,就会自动加载applicationContext.xml文件,所以定时任务会立即被执行。

如果想要避免这种错误的发生,最简单的方法就是。将需要启动服务器之后,立刻就要知道的内容,例如

<context:component-scan base-package="control"/>
<mvc:annotation-driven />

,加到applicationContext.xml文件中即可。
另一种方法就是,将spring的所有配置文件都放在context-param(上下文参数)中进行加载,例如:

<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:applicationContext.xml,
            classpath:spring-servlet.xml
        </param-value>
    </context-param>

这样所有的问题就可以解决。

总结

从上面出现的问题,我们不难发现。spring框架在加载web配置文件的时候。首先加载的是context-param配置的内容,而并不会去初始化servlet。只有进行了网站的跳转,经过了DispatcherServlet的导航的时候,才会初始化servlet,从而加载init-param中的内容。

<?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>springMVC</display-name> <welcome-file-list> <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file> </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-mybatis.xml</param-value> </context-param> <filter> <filter-name>encodingFilter</filter-name> <filter-class> org.springframework.web.filter.CharacterEncodingFilter </filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.properties</param-value> </context-param> <context-param> <param-name>webAppRootKey</param-name> <param-value>keshe_C12_09.root</param-value> </context-param> <listener> <listener-class> org.springframework.web.util.Log4jConfigListener </listener-class> </listener> </web-app>
最新发布
07-16
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值