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>

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

分析解决 spring quartz 中出现的执行两次问题的更多相关文章

  1. 解决Spring+Quartz无法自动注入bean问题

    问题 我们有时需要执行一些定时任务(如数据批处理),比较常用的技术框架有Spring + Quartz中.无奈此方式有个问题:Spring Bean无法自动注入. 环境:Spring3.2.2 + Q ...

  2. 解决Spring Security自定义filter重复执行问题

    今天做项目的时候,发现每次拦截器日志都会打两遍,很纳闷,怀疑是Filter被执行了两遍.结果debug之后发现还真是!记录一下这个神奇的BUG! 问题描述 项目中使用的是Spring-security ...

  3. 解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException

    解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException这个问题出现的原因:一般在使用annotation的方式注入spring的bean 出现的,具体 ...

  4. 关于Spring中,定时任务执行两次的解决办法

    原因:如果spring-quartz.xml文件,在Spring的配置文件spring-config.xml中被加载,那么定时任务会被Spring和SpringMVC扫描两次,所以会被执行两次. 解决 ...

  5. 解决Spring Cloud中Feign第一次请求失败的问题

    在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 com.netflix.hystrix.exception.HystrixTimeoutE ...

  6. Spring5源码,Spring Web中的处理程序执行链

    一.什么是Spring中的处理程序执行链? 二.HandlerExecutionChain类 三.自定义处理程序执行链 Spring的DispatcherServlet假如缺少几个关键元素将无法分派请 ...

  7. 解决spring boot中rest接口404,500等错误返回统一的json格式

    在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...

  8. Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题

    Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只 ...

  9. Spring Boot 中实现定时任务的两种方式

    在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Qua ...

随机推荐

  1. [Objective-C语言教程]类型定义:typedef(19)

    Objective-C编程语言提供了一个名称为typedef的关键字,可以使用此关键字为类型指定新名称. 以下是为单字节数字定义术语BYTE的示例 - typedef unsigned char BY ...

  2. java springboot+maven发送邮件

    springboot+maven发送邮件 废话不多说直接上代码 1. pom 文件导入jar包 <!--邮件发送--> <dependency> <groupId> ...

  3. python+selenium 定位隐藏元素

    定位隐藏要素的原理:页面主要通过“display:none”来控制元素不可见.所以我们需要通过javaScript修改display的值得值为display="block,来实现元素定位的. ...

  4. 4、2支持向量机SVM算法实践

    支持向量机SVM算法实践 利用Python构建一个完整的SVM分类器,包含SVM分类器的训练和利用SVM分类器对未知数据的分类, 一.训练SVM模型 首先构建SVM模型相关的类 class SVM: ...

  5. github访问慢加速访问

    实测从1kb到了1m多 方法: 登录 https://www.ipaddress.com/ 输入github.com得到一个或两个IP地址 输入github.global.ssl.fastly.net ...

  6. [BZOJ 5072][Lydsy1710月赛]小A的树

    传送门 \(\color{green}{solution}\) 嗯...其实我也不太会,所以大胆猜个结论吧(后来证了一下,然后放弃了...). 我们发现如果要使一个联通块的黑点数量为\(k\)的方案最 ...

  7. windows 虚拟机VMware 安装linux系统注意事项!!!

    1.主机CPU是否支持虚拟化技术?      启动 CPUZ 软件(如下图) 注: 32位系统查看使用CPUZ_x86软件             64位系统查看使用CPUZ_x64软件    启动后 ...

  8. php 根据子分类循环获取其父级分类

    /** * 根据子分类循环获取其父级分类 */ function goodsCatPath($catId, $data = []){ if($catId==0)return $data; $data[ ...

  9. Kali/Ubuntu无法和物理机之间复制粘贴解决办法

    Vmware安装Linux,传统的vmtools已经被抛弃,当前建议使用Open-VM-tools 安装Open-VM-tools//Kali,Ubuntu: sudo apt install Ope ...

  10. 在Windows Server 2008 R2(x64)上安装.NET Framework 4.5 兼谈.NET Framework 4.0 “在服务器核心角色上不受支持”含义

    完成了一个服务器文件监控系统,该系统的核心是一个Windows服务,需要安装在服务器上.由于是Visual Studio 2012开发,为了保证开发的Windows服务可以运行,必须在Windows服 ...