1.摘要:Quartz是Java领域的开源任务调度工具,是一个任务调度框架,通过触发器设置作业的定时运行规则,来执行定时任务。在项目中使用频繁,本文将在SSM整合项目上整合Quartz框架实现任务调度。
基础项目的搭建参考文章:https://blog.csdn.net/caiqing116/article/details/84573166
项目git地址:https://github.com/gitcaiqing/SSM_DEMO.git
2.项目搭建
(1)Maven引入需要的Quartz相关jar包
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
(2)添加spring–>application-quartz.xml配置
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd"
default-lazy-init="true">
<!-- 密码过期提醒任务调度 -->
<bean id="jobPasswordExpired" class="com.ssm.quartz.PasswordExpiredQuartz" />
<bean id="jobPasswordExpiredDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="jobPasswordExpired" />
<property name="targetMethod" value="doTask" />
<!-- 是否支持并发 true 支持; false不支持,等上一个调度任务执行完才会执行,如果间隔时间小于任务执行时间第二个调度任务启动但会推迟执行 -->
<property name="concurrent" value="false" />
</bean>
<bean id="jobPasswordExpiredTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="jobPasswordExpiredDetail" />
<!-- 每隔30秒执行一次:0 */30 * * * ? -->
<property name="cronExpression" value="*/30 * * * * ?"/>
</bean>
<!-- 总管理类如果将lazy-init='false'那么容器启动就会执行调度程序 -->
<bean id="startQuertz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" lazy-init="true" >
<property name="triggers">
<!-- 作业调度器,list下可加入其他的调度器 -->
<list>
<ref bean="jobPasswordExpiredTrigger" />
</list>
</property>
</bean>
</beans>
(3)任务调度实现com.ssm.quartz.PasswordExpiredQuartz .java
package com.ssm.quartz;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 密码过期任务调度
* @author https://blog.csdn.net/caiqing116
*/
public class PasswordExpiredQuartz {
private static final Logger log = LoggerFactory.getLogger(PasswordExpiredQuartz.class);
public void doTask() {
log.info("密码过期提醒任务调度开始执行");
//查询用户表数据更新时间大于一定天数的 TODO
//给用户发送短信或邮件 TODO
log.info("密码过期提醒任务调度执行结束");
}
}
(4)关键属性concurrent详解
在上文中可以看到设置了属性concurrent如果需要支持并发则配置为
<property name="concurrent" value="true" />
不支持配置为
<property name="concurrent" value="false" />
这里对此属性说明:对于相同的Job, 很可能第一个job完成之前,第二个job就开始了。指定concurrent设为false,第一个及后续的job不会并发运行,第二个job将不会在第一个job完成之前开始。那么第二个job是按时启动了然后被推迟执行还是被取消了呢?这里呢,我们可以将上文中的调度任务实现执行过程中暂停40s,这样两个job之间将会有时间重叠,测试后发现第一个job执行完第二个job马上启动了。结论:第二个job是按时启动了然后被推迟执行
(5)cron表达式详解大全
Cron的表达式被用来配置CronTrigger实例。 cron的表达式是字符串
1. Seconds
2. Minutes
3. Hours
4. Day-of-Month
5. Month
6. Day-of-Week
7. Year (可选字段)
每一个字段都有一套可以指定有效值,如
Seconds (秒) :可以用数字0-59 表示,
Minutes(分) :可以用数字0-59 表示,
Hours(时) :可以用数字0-23表示,
Day-of-Month(天) :可以用数字1-31 中的任一一个值,但要注意一些特别的月份
Month(月) :可以用0-11 或用字符串 “JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV and DEC” 表示
Day-of-Week(每周):可以用数字1-7表示(1 = 星期日)或用字符口串“SUN, MON, TUE, WED, THU, FRI and SAT”表示
“/”:为特别单位,表示为“每”如“0/15”表示每隔15分钟执行一次,“0”表示为 从“0”分开始, “3/20”表示表示每隔20分钟执行一次,“3”表示从第3分钟开始执行
“?”:表示每月的某一天,或第周的某一天
“L”:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如“6L”表示“每月的最后一个星期五”
“W”:表示为最近工作日,如“15W”放在每月(day-of-month)字段上表示为“到本月15日最近的工作日”
““#”:是用来指定“的”每月第n个工作日,例 在每周(day-of-week)这个字段中内容为"6#3" or “FRI#3” 则表示“每月第三个星期五”
范例大全
每隔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 * * ?