分析解决 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>
再次启动工程,问题解决。
分析解决 spring quartz 中出现的执行两次问题的更多相关文章
- 解决Spring+Quartz无法自动注入bean问题
问题 我们有时需要执行一些定时任务(如数据批处理),比较常用的技术框架有Spring + Quartz中.无奈此方式有个问题:Spring Bean无法自动注入. 环境:Spring3.2.2 + Q ...
- 解决Spring Security自定义filter重复执行问题
今天做项目的时候,发现每次拦截器日志都会打两遍,很纳闷,怀疑是Filter被执行了两遍.结果debug之后发现还真是!记录一下这个神奇的BUG! 问题描述 项目中使用的是Spring-security ...
- 解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException
解决spring配置中的bean类型的问题:BeanNotOfRequiredTypeException这个问题出现的原因:一般在使用annotation的方式注入spring的bean 出现的,具体 ...
- 关于Spring中,定时任务执行两次的解决办法
原因:如果spring-quartz.xml文件,在Spring的配置文件spring-config.xml中被加载,那么定时任务会被Spring和SpringMVC扫描两次,所以会被执行两次. 解决 ...
- 解决Spring Cloud中Feign第一次请求失败的问题
在Spring Cloud中,Feign和Ribbon在整合了Hystrix后,可能会出现首次调用失败的问题 com.netflix.hystrix.exception.HystrixTimeoutE ...
- Spring5源码,Spring Web中的处理程序执行链
一.什么是Spring中的处理程序执行链? 二.HandlerExecutionChain类 三.自定义处理程序执行链 Spring的DispatcherServlet假如缺少几个关键元素将无法分派请 ...
- 解决spring boot中rest接口404,500等错误返回统一的json格式
在开发rest接口时,我们往往会定义统一的返回格式,列如: { "status": true, "code": 200, "message" ...
- Spring AOP动态代理实现,解决Spring Boot中无法正常启用JDK动态代理的问题
Spring AOP底层的动态代理实现有两种方式:一种是JDK动态代理,另一种是CGLib动态代理. JDK动态代理 JDK 1.3版本以后提供了动态代理,允许开发者在运行期创建接口的代理实例,而且只 ...
- Spring Boot 中实现定时任务的两种方式
在 Spring + SpringMVC 环境中,一般来说,要实现定时任务,我们有两中方案,一种是使用 Spring 自带的定时任务处理器 @Scheduled 注解,另一种就是使用第三方框架 Qua ...
随机推荐
- 30 个免费的 Sketch 必备插件
简评:中秋三天小长假,要不要学点啥?比如简单的设计?比如用 Sketch 做个项目? Sketch 有许多值得称赞的地方,其丰富的插件就是亮点之一.Sketch 的社区有着大量免费高效的插件.今天这篇 ...
- Bootstrap Table使用方法详解
http://www.jb51.net/article/89573.htm bootstrap-table使用总结 bootstrap-table是在bootstrap-table的基础上写出来的,专 ...
- Xcode 编译更改 Build 输出路径
Xcode新建一个工程,build之后,可执行文件一般在 ~/Library/Developer/Xcode/DerivedData 下. 可以把这个路径指定为当前工程目录.  指定方法 Xcode ...
- JavaScript的几种(原型)继承
定义Foo,Bar 其中,Bar继承Foo a是Bar的实例,包含有Foo和Bar的函数和属性: function Foo(name) { this.name = name; } Foo.protot ...
- 1059 C语言竞赛 (20 分)
#include <iostream> #include <iomanip> #include <cmath> using namespace std; <& ...
- windows 虚拟机VMware 安装linux系统注意事项!!!
1.主机CPU是否支持虚拟化技术? 启动 CPUZ 软件(如下图) 注: 32位系统查看使用CPUZ_x86软件 64位系统查看使用CPUZ_x64软件 启动后 ...
- 等价类计数问题(Polya定理和burnside引理)
零.约定: (置换等名词会在前置知识中有解释) \(1.\)在本文中,题目要求的染色方案等统称为"元素". \(2.\)两个元素严格相等我们记做"\(=\)", ...
- docker + nginx 部署vuejs3.0项目
1:用指令 npm run build 打包vusjs项目(该项目是在github上下载的).打包成功后会生成一个目录dist. 2:把该文件夹拷贝到腾讯云服务器(操作系统 centos7)下的/us ...
- 查看哪个用户、IP、什么时间登陆过服务器
2019-01-07 utmpdump /var/log/wtmp 或者 who /var/log/wtmp
- android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法
MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...