spring集成Quartz:
首先第一步肯定是在pom文件中导入相关的包。pom.xml:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
在Spring中使用Quartz有两种方式实现:第一种是任务类继承QuartzJobBean,第二种则是在配置文件里定义任务类和要执行的方法,类和方法可以是普通类。很显然,第二种方式远比第一种方式来的灵活,我这里使用的是第二种配置方式,大家有兴趣可以自己试一下第一中配置方式。
先来 spring配置文件:
<!-- job -->
<bean id="oceanStatusJob" class="com.perf.job.OceanStatusJob"/>
<!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现Job接口,通过targetMethod指定调用方法-->
<!-- jobDetail -->
<bean id="oceanJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="oceanStatusJob"/>
<property name="targetMethod" value="doIt"/>
<!--false表示等上一个任务执行完后再开启新的任务,这里和上一遍博客中的注解@DisallowConcurrentExecution一个道理-->
<property name="concurrent" value="false"/>
</bean>
<!-- Trigger-->
<bean id="oceanStatusCronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="oceanJob"/>
<property name="cronExpression" value="0 */2 * * * ?"/>
</bean>
<!--Scheduler -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="oceanStatusCronTrigger"/>
</list>
</property>
</bean>
对应的 OceanStatusJob实体类:
public class OceanStatusJob {
public void doIt() {
System.out.println("工单job");
}
}
ok,这里给大家解释下xml文件的内容。
回想一下之前说过的Quartz三个要素:Scheduler、Trigger、JobDetai&Job。对应到xml文件,也就是上面的中的几个bean对象。几个点注意下:
一个scheduler可以对应多个Trigger:看bean对象也看出来了,它的属性是个list集合。
一个job可以对应多个JobDetail:这个其实也好理解,毕竟具体的实现是job实现,但是通过jobDetail去管理job。就好比游戏和外挂,总不能你同一个游戏开两个客户端,你还买2个挂吧?外挂相当于管理游戏的也就是JobDetail,而游戏相等于具体的实现Job。
job可以自己指定方法名: 之前job都是通过实现job接口,实现execute方法。现在只需要通过jobDetai的属性targetMethod指定执行方法,但是需要注意这个jobDetail它是使用MethodInvokingJobDetailFactoryBean作为具体实现。
文章最后给大家附上一些常用的Cron表达式。
自己思考:
如何动态添加定时任务?
前面是采用配置文件的形式整合spring和Quartz,如果需求比较简单这样就可以满足了,但是很多时候,我们都需要修改新增任务,现在我采用的方式是每次修改或者新增任务之后,都需要重新启动项目。很明显这种方式不够灵活(毕竟方便),那么我们如何才能在不重启项目的前提下,修改或者新增任务呢(类似于从数据库获取任务)。
附:
字段名 允许的值 允许的特殊字符
秒 0-59 , - * /
分 0-59 , - * /
小时 0-23 , - * /
日 1-31 , - * ? / L W C
月 1-12 or JAN-DEC , - * /
周几 1-7 or SUN-SAT , - * ? / L C #
年 (可选字段) empty, 1970-2099 , - * /
“?”字符:表示不确定的值
“,”字符:指定数个值
“-”字符:指定一个值的范围
“/”字符:指定一个值的增加幅度。n/m表示从n开始,每次增加m
“L”字符:用在日表示一个月中的最后一天,用在周表示该月最后一个星期X
“W”字符:指定离给定日期最近的工作日(周一到周五)
“#”字符:表示该月第几个周X。6#3表示该月第3个周五
2)Cron表达式范例:
每隔5秒执行一次:*/5 * * * * ?
每隔1分钟执行一次:0 */1 * * * ?
每天23点执行一次:0 0 23 * * ?
每天凌晨1点执行一次:0 0 1 * * ?
每月1号凌晨1点执行一次:0 0 1 1 * ?
每月最后一天23点执行一次:0 0 23 L * ?
每周星期天凌晨1点实行一次:0 0 1 ? * L
在26分、29分、33分执行一次:0 26,29,33 * * * ?
每天的0点、13点、18点、21点都执行一次:0 0 0,13,18,21 * * ?