朋友的项目中有点问题。他那边是spring架构的,有一个比较简单的需要定时的任务执行。在了解了他的需求之后,于是提出了比较简单的spring+quartz的实现方式。
注意本文只是讨论,在已搭建完毕的spring工程下,完成最简单的定时任务。
第一步,要知道spring这个架构,很有趣很有意思。可以做到自由插拔功能模块的效果。工程项目是基于maven包依赖管理的,所以把这次需要的依赖包引用列出来:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!-- 定时器依赖 开始 --> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-context-support</artifactid> <version> 4.0 . 2 .release</version> </dependency> <dependency> <groupid>org.quartz-scheduler</groupid> <artifactid>quartz</artifactid> <version> 2.2 . 1 </version> </dependency> <!-- 定时器依赖 结束 --> |
当然,这是要跟对应的spring的版本是要匹配的。我们这里的工程是4.0.2。前一个包spring-context-support,主要的作用是作为spring与quartz的沟通管理的部件,如果注释掉就会报这样的错误
在maven配置完所需要添加的包之后(其他的包,这里暂时不扩展开说了,本文只讨论在完整spring工程项目下的配置),我们就可以开始动手给这个项目添加,定时任务的功能模块了。
第二步,从web的项目的起源,web.xml 中改动做起。由于原本的项目spring的配置文件是spring-mvc.xml,我这里就把定时任务的配置文件改成了spring-time.xml。这样就可以通过同一个扫描的配置在启动的时候去读取了。具体的代码如下:
1
2
3
4
|
<context-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:spring-*.xml</param-value> </context-param> |
然后给大家看一下我的工程结构:
通过这样的配置,项目就会知道怎么去调用了。实现了这一步接下来我们就可以继续往下走了;
第三步,就是要完成spring-timer.xml这个定时任务的核心配置了。在这个文件配置中,我们主要是完成三件事情:
1.配置启动的设置,关于懒加载(简单说一下,比如把某个变量初始化为null,也是一种懒加载,即在服务启动之后,只有在实际被调用的时候才会实例化,否则是不会在内存中存在的,只是逻辑上的。可以省空间,但是也可能会导致,问题延迟很久才会被发现,此处不再详细解说),以及触发器的配置;
2.quartz-2.x的配置,包含定时任务触发之后要调用的job的名字,以及corn表达式(即定时表达式,控制程序在何时重复执行的原因,本次在会在后续补充关于cron表达式的内容);
3.配置job的内容和job对应的具体的类。
好了逻辑流程解说完毕,上代码:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
<?xml version= "1.0" encoding= "utf-8" ?> <beans xmlns= "http://www.springframework.org/schema/beans" xmlns:xsi= "http://www.w3.org/2001/xmlschema-instance" xmlns:p= "http://www.springframework.org/schema/p" xsi:schemalocation="http: //www.springframework.org/schema/beans http: //www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 启动触发器的配置开始 --> <bean name= "startquertz" lazy-init= "false" autowire= "no" class = "org.springframework.scheduling.quartz.schedulerfactorybean" > <property name= "triggers" > <list> <ref bean= "myjobtrigger" /> </list> </property> </bean> <!-- 启动触发器的配置结束 --> <!-- 调度的配置开始 --> <!-- quartz- 1.8 以前的配置 <bean id= "myjobtrigger" class = "org.springframework.scheduling.quartz.crontriggerbean" > <property name= "jobdetail" > <ref bean= "myjobdetail" /> </property> <property name= "cronexpression" > <value> 0 / 1 * * * * ?</value> </property> </bean> --> <!-- quartz- 2 .x的配置 --> <bean id= "myjobtrigger" class = "org.springframework.scheduling.quartz.crontriggerfactorybean" > <property name= "jobdetail" > <ref bean= "myjobdetail" /> </property> <property name= "cronexpression" > <value> 0 / 10 * * * * ?</value> <!-- <value> 1 52 * * * ?</value> --> </property> </bean> <!-- 调度的配置结束 --> <!-- job的配置开始 --> <bean id= "myjobdetail" class = "org.springframework.scheduling.quartz.methodinvokingjobdetailfactorybean" > <property name= "targetobject" > <ref bean= "myjob" /> </property> <property name= "targetmethod" > <value>work</value> </property> </bean> <!-- job的配置结束 --> <!-- 工作的bean --> <bean id= "myjob" class = "com.tec.kevin.quartz.jobtest" /> </beans> |
完成这里的配置文件配置之后,就可以开始下一步,具体的业务逻辑实现了;
第四步,具体业务逻辑实现。
这里要注意的是下图中的两个点
上图是具体的业务实现的类,里面的名字和下图定时任务配置的要相同。
完成上述之后,我们可以启动项目看看实际效果了。
这里可以看到,定时任务按照我们之前在配置中的 <value>0/10 * * * * ?</value> 每10秒执行一次 来运行了。
要注意的是,在实现这个方法的过程中,我遇到了重复执行的情况。就是同一个时间,执行了两次。后来找到的原因是在配置web.xml的时候,重复配置了定时任务,这样导致执行了多次。要是有遇到这个情况的,可以参考我的解决方法。
接来下会有两篇文章,一篇是写定时任务的更简单的实现方法,另外一篇讲解cron 表达式。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。