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>

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

  • 相关阅读:
    序列化-请求数据校验。。。。。。
    python自动化测试-D5-学习笔记之二(常用模块之加密模块)
    python自动化测试-D5-学习笔记之二(常用模块之os,sys,random,string,time)
    python自动化测试-D5-学习笔记之二(常用模块之json模块)
    python自动化测试-D5-学习笔记之一(argv的使用)
    python自动化测试-D5-学习笔记之一(函数补充,内置函数,map,filter,eval)
    python习题:写一个函数打印两个字典中不一样的key和value
    python习题:用文件方式编写购物车程序,添加,查看和删除
    python习题:时间格式转换
    python习题:双色球
  • 原文地址:https://www.cnblogs.com/reycg-blog/p/7857301.html
Copyright © 2011-2022 走看看