我是靠谱客的博主 魔幻帅哥,这篇文章主要介绍spring+quartz定时任务启动服务后没有马上执行,现在分享给大家,希望可以做个参考。

写了一个spring+quartz的定时任务,但是发现tomcat正常启动后并没有马上执行。网上也没找到能解决的办法,只能自己慢慢试。此文章是自己作为笔记用的,仅供参考。本人菜鸟,文中很多用词可能不当,勿喷。

spring+quartz定时任务网上有很多资料可以参考,我这里就不多说了,直接贴上我的代码。

1.项目结构


2.pom.xml添加包

复制代码
1
2
3
4
5
6
<!-- 定时任务 --> <dependency>     <groupId>org.quartz-scheduler</groupId>     <artifactId>quartz</artifactId>     <version>2.3.0</version> </dependency>

3.spring-quartz.xml

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 启动触发器的配置开始 --> <!--lazy-init="false" 表示不需要延迟加载,容器启动就会执行--> <bean id="quartzsScheduler" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="imageTrigger" /> </list> </property> </bean> <!-- 触发器 quartz的配置 --> <bean id="imageTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="testJobDetail" /> <!-- 每天8点到22点,每半小时触发一次 --> <property name="cronExpression" value="0 0/30 8-22 * * ?" /> </bean> <!-- job的配置开始 --> <bean id="testJobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <!-- 调用的类 --> <property name="targetObject" ref="orderImageService" /> <!-- 调用类中的方法 --> <property name="targetMethod" value="queryOrderImageFromOCR" /> </bean> </beans>

4.修改之前的spring-mvc.xml

复制代码
1
2
3
4
5
6
7
8
<!-- 定时任务管理 --> <import resource="classpath:/spring/spring-quartz.xml"/> <!-- bean管理 --> <import resource="classpath:/spring/spring-bean.xml"/>

5.web.xml

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<servlet>     <servlet-name>microManager</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <init-param>         <param-name>contextConfigLocation</param-name>         <param-value>                 classpath*:spring/spring-mvc.xml         </param-value>     </init-param> </servlet> <servlet-mapping>     <servlet-name>microManager</servlet-name>     <!-- 所有的的请求,都会被DispatcherServlet处理 -->     <url-pattern>*.do</url-pattern> </servlet-mapping>
复制代码
1
复制代码
1
2
3
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>

定时任务具体执行的方法就不写了,根据自己的需求来。

按照上述的配置,在正常启动tomcat后,并没有马上执行配置的定时任务,必须要项目里有方法被调用后才会执行。

查了很久资料,发现web.xml中必须直接加载配置定时任务的xml文件,而我写的是web.xml直接加载spring-mvc.xml,然后在spring-mvc.xml中引入spring-quartz.xml。

于是,我在web.xml中添加了

复制代码
1
2
3
4
<context-param>     <param-name>contextConfigLocation</param-name>     <param-value>classpath*:spring/spring-quartz.xml</param-value> </context-param>

然后重启服务,这次定时任务马上执行了。

可是又出现了新的问题:项目中用的mybatis,定时任务执行的方法中也有对数据库的操作,而数据库的配置配置配置,注解的配置都是在spring-mvc.xml中的,在调用对数据库操作的方法(orderRecordMapper.selectByState(state))时报错,原因是orderRecordMapper为null。

这就意味着当我的web.xml中的内容为

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<context-param>     <param-name>contextConfigLocation</param-name>     <param-value>classpath*:spring/spring-quartz.xml</param-value> </context-param> <listener>     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet>     <servlet-name>microManager</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <init-param>         <param-name>contextConfigLocation</param-name>         <param-value>                 classpath*:spring/spring-mvc.xml         </param-value>     </init-param> </servlet> <servlet-mapping>     <servlet-name>microManager</servlet-name>     <!-- 所有的的请求,都会被DispatcherServlet处理 -->     <url-pattern>*.do</url-pattern> </servlet-mapping>

时,spring-quartz.xml是加载了,但是spring-mvc.xml中的内容好像就失效了,至少是不能共用的,具体原因还不太清楚,对这块的知识太欠缺了,但是并不影响我解决问题。

于是我又修改了web.xml文件为

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<context-param>     <param-name>contextConfigLocation</param-name>     <param-value> classpath*:spring/spring-quartz.xml classpath*:spring/spring-mvc.xml     </param-value> </context-param> <listener>     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet>     <servlet-name>microManager</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping>     <servlet-name>microManager</servlet-name>     <!-- 所有的的请求,都会被DispatcherServlet处理 -->     <url-pattern>*.do</url-pattern> </servlet-mapping>

OK了,tomcat重新启动后,定时任务马上执行,而且执行的方法也没有问题。

你以为就这样结束了么,那你就错了。

我既然改动了<servlet-mapping>中的内容,那么会不会对我的http接口有影响呢,果然,测试发现原来能正常调用的接口,现在调用报错,说找不到microManager-servlet.xml。WTF什么鬼,项目里根本没有这个xml,不过有microManager,那么肯定就是由于改动了<servlet-mapping>中的内容导致的。

好吧,我再次改动web.xml,所幸,这次改动后一切都正常,终于搞定了。中间的过程省略了很多,因为自己只是的羸弱,只能靠摸索,反正花了很长时间。

web.xml终极版:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<context-param>     <param-name>contextConfigLocation</param-name>     <param-value>                 classpath*:spring/spring-quartz.xml                 classpath*:spring/spring-mvc.xml     </param-value> </context-param> <listener>     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet>     <servlet-name>microManager</servlet-name>     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     <init-param>         <param-name>contextConfigLocation</param-name>         <param-value>classpath*:spring/spring-mvc.xml</param-value>     </init-param> </servlet> <servlet-mapping>     <servlet-name>microManager</servlet-name>     <!-- 所有的的请求,都会被DispatcherServlet处理 -->     <url-pattern>*.do</url-pattern> </servlet-mapping>

这个问题总算告一段落,可解决这个问题的过程中又出现很多新的问号:

1.web.xml中param-name为contextConfigLocation的地方有两处,为何没有影响?如果把contextConfigLocation换成其他自定义的名字会不会有影响?

2.web.xml中context-param表示什么意思?

3.web.xml中不直接加载定时任务的spring-quartz.xml的情况下启动服务为何不马上执行?

4.web.xml中配置了spring-quartz.xml,为何对于mapper的注解失效?

这些问题还需要后续去弄明白,大家也可以和我一起探究(ps:大神就不用了哈)。

第一次分享,很多地方写的有问题,欢迎大家批评指教哈,有不清楚的地方也可以指出来的,我会一一解答,如果我也不清楚就没得办法了。哈哈。




最后

以上就是魔幻帅哥最近收集整理的关于spring+quartz定时任务启动服务后没有马上执行的全部内容,更多相关spring+quartz定时任务启动服务后没有马上执行内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(67)

评论列表共有 0 条评论

立即
投稿
返回
顶部