zoukankan      html  css  js  c++  java
  • 分析解决 spring quartz 中出现的执行两次问题

    1. 问题描述

    在开发询盘功能时,遇到一个需求,就是后台定时任务执行用电施工业务的工单下发。

    使用的技术是 spring quartz,因为其他应用有先例,配置quartz 完成后,先写了一个 helloworld 测试下。

    然而却发现,每次到定时时间后,程序都会执行两次。

    2. 分析过程

    先使用 bing 搜索了下看别人是否也遇到过类似问题,果然有。

    http://blog.csdn.net/jiang117/article/details/43077275

    上面文档的作者,查找的原因是 ContextLoaderListener 和 DispatcherServlet 对应用上下文重复加载,导致问题出现。

    给出的解决方法如下:

    带着这个疑惑,我检查一下自己项目的 web.xml 文件,发现果然有问题。

    下面是 ContextLoaderListener 中加载的上下文。

      <!-- 加载Spring和Mybatis的配置信息 -->
        <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 上下文中所有的配置都会被实例化两次,因此也就会导致该问题出现。

    3. 解决过程

    找到了问题原因,下一步就要修改 web.xml 中的配置,解决 spring-all xml 上下文被实例化两次的问题。

    解决问题之前,先要弄清楚 DispatcherServlet 和 ContextLoaderListener 这两个应用上下文之间的关系。

    下面的内容选自 《spring 实战 第4版》 p139

    两个应用上下文之间的故事
    
    当 DispatcherServlet 启动的时候,它会创建 Spring 上下文,并加载配置文件或者配置类中所声明的 bean。
    
    同时在 Spring Web 应用中,通常还有一个另外的应用上下文,它由 ContextLoaderListener 创建。
    
    两者的分工有所不同, DispatcherServlet 中加载 Web 组件的 bean,如 Controller,viewResolver 以及处理器映射。
    而ContextLoaderListener 要加载应用中其他的 bean,这些 bean 通常是驱动应用后端的中间层和数据层组件。

    同时在如下博客链接 http://www.cnblogs.com/weknow619/p/6341395.html 得到说明:

     因此决定使用 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>

    再次启动工程,问题解决。

  • 相关阅读:
    leetcode 268. Missing Number
    leetcode 189. Rotate Array
    leetcode 118. Pascal's Triangle 、119. Pascal's Triangle II 、120. Triangle
    HDU高精度总结(java大数类)
    一起talk C栗子吧(第八十七回:C语言实例--使用管道进行进程间通信概述)
    iOS敏捷开发之道,经常使用的宏定义总结
    360 网络攻防 hackgame 解题报告(通关)
    打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
    数列求和
    指尖上的电商---(11)Windows平台部署SolrCloud
  • 原文地址:https://www.cnblogs.com/reycg-blog/p/7857301.html
Copyright © 2011-2022 走看看