首页> 软件工程> Quartz+Spring定时任务调度两次解决方案

[文章]Quartz+Spring定时任务调度两次解决方案

收藏
0 705 0

问题现象:

项目运行过程中,发现Spring集成Quartz存在某个时刻任务运行两次的问题。而且此问不经常出现,偶尔出现。下面提供下解决方案:

下面是 ContextLoaderListener 中加载的上下文

复制代码

  <!-- 加载SpringMybatis的配置信息 -->

    <context-param>

        <param-name>contextConfigLocation</param-name>

        <param-value>/WEB-INF/classes/spring/spring-all.xml</param-value>

    </context-param>

    <!-- Spring监听器 -->

    <listener>

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

    </listener>

复制代码

这是 DispatcherServlet 加载的上下文

复制代码

        <!-- Spring MVC servlet -->

    <servlet>

        <servlet-name>SpringMVC</servlet-name>

        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

        <init-param>

            <param-name>contextConfigLocation</param-name>

            <param-value>/WEB-INF/classes/spring/spring-all.xml</param-value>

        </init-param>

        <load-on-startup>1</load-on-startup>

        <async-supported>true</async-supported>

    </servlet>

    <servlet-mapping>

        <servlet-name>SpringMVC</servlet-name>

        <url-pattern>/</url-pattern>

    </servlet-mapping>

经过对比发现,两个上下文都会加载 /WEB-INF/classes/spring/spring-all.xml spring-all.xml 文件则包含了所有的 spring 配置文件,也就是所有的上下文配置。

这样就会产生一个问题,就是  spring-all .xml 上下文中所有的配置都会被实例化两次,因此也就会导致该问题出现。

 

解决方案:

两个应用上下文之间的故事
 DispatcherServlet 启动的时候,它会创建 Spring 上下文,并加载配置文件或者配置类中所声明的 bean
 
同时在 Spring Web 应用中,通常还有一个另外的应用上下文,它由 ContextLoaderListener 创建。
 
两者的分工有所不同, DispatcherServlet 中加载 Web 组件的 bean,如 ControllerviewResolver 以及处理器映射。
ContextLoaderListener 要加载应用中其他的 bean,这些 bean 通常是驱动应用后端的中间层和数据层组件。
 
 
 因此决定使用 ContextLoaderListener 加载所有配置,而将 DispatchServlet 上下文去除
 
 
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/classes/spring/spring-all.xml</param-value>
    </context-param>
 
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
        <!-- Spring MVC servlet -->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value></param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
        <async-supported>true</async-supported>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>

    </servlet-mapping>
软件工程
最近热帖
{{item.Title}} {{item.ViewCount}}
近期热议
{{item.Title}} {{item.PostCount}}