Quartz介绍
Quartz是Job scheduling(作业调度)领域的一个开源项目,Quartz既可以单独使用也可以跟spring框
架整合使用,在实际开发中一般会使用后者。使用Quartz可以开发一个或者多个定时任务,每个定时任
务可以单独指定执行的时间,例如每隔1小时执行一次、每个月第一天上午10点执行一次、每个月最后
一天下午5点执行一次等。
官网:http://www.quartz-scheduler.org/
简单使用(使用步奏与解释在代码注释中)
搭建maven工程
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.fs</groupId>
<artifactId>QuartzDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!-- quartz 定时器-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
</dependencies>
</project>
applicationContext-jobs.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 把自定义的定时任务类(这个类是个普通类,里面需要自己编写定时执行的方法)springIOC管理-->
<bean id="quartzHelloWorld" class="com.fs.regularwork.QuartzHelloWorld">
</bean>
<!-- 设置第二个定时类-->
<bean id="quartzHelloWorld02" class="com.fs.regularwork.QuartzHelloWorld02"></bean>
<!-- 将方法调用作业详细信息工厂Bean交给ioc管理-->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 注入自定义的定时任务类的对象-->
<property name="targetObject" ref="quartzHelloWorld"/>
<!-- 注入自定义调用对象的具体执行的方法-->
<property name="targetMethod" value="quartzTest"/>
</bean>
<!-- 将方法调用作业详细信息工厂Bean交给ioc管理-->
<bean id="jobDetail02" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!-- 注入自定义的定时任务类的对象-->
<property name="targetObject" ref="quartzHelloWorld02"/>
<!-- 注入自定义调用对象的具体执行的方法-->
<property name="targetMethod" value="quartzTest02"/>
</bean>
<!-- 注册一个触发器,指定任务触发时间,触发上面指定的方法-->
<bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 注入jobDetail,通过反射来调用我们上面自定义的方法-->
<property name="jobDetail" ref="jobDetail"/>
<!-- 指定触发事件,基于Cron表达式-->
<property name="cronExpression">
<!-- 从0秒开始,每10秒执行一次,测试功能使用-->
<value>0/10 * * * * ? </value>
<!-- 从每天的3点开始执行一次-->
<!-- <value>0 0 3 * * ? </value>-->
<!-- 从0小时开始,30分钟执行一次 -->
<!-- <value>0 0/30 * * * ?</value>-->
</property>
</bean>
<!-- 注册一个触发器,指定任务触发时间,触发上面指定的方法-->
<bean id="myTrigger02" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!-- 注入jobDetail,通过反射来调用我们上面自定义的方法-->
<property name="jobDetail" ref="jobDetail02"/>
<property name="cronExpression">
<value>0/10 * * * * ? </value>
</property>
</bean>
<!-- 统一注册一个调度工厂,通过这个调用工厂调度触发器任务 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!-- 可以注入多个触发器-->
<property name="triggers">
<list>
<!-- 注入上面触发器,可以注入多个,我由于上面配置了2个,所以我注入2个测试能否10秒执行方法-->
<ref bean="myTrigger"/>
<ref bean="myTrigger02"/>
</list>
</property>
</bean>
</beans>
java config方式(伪代码)
package com.fs.config;
import com.fs.controller.JorumServerRegister;
import org.quartz.JobDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfig {
//注入统一任务类
@Autowired
private 任务类 jorumServerRegister;
@Bean("heartbeat")
public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(){
MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
//注入自定义的定时任务类的对象
methodInvokingJobDetailFactoryBean.setTargetObject(jorumServerRegister);
//注入自定义调用对象的具体执行的方法
methodInvokingJobDetailFactoryBean.setTargetMethod("heartbeat");
return methodInvokingJobDetailFactoryBean;
}
//触发器
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(@Autowired @Qualifier("heartbeat") MethodInvokingJobDetailFactoryBean heartbeat){
CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
// 注入jobDetail,通过反射来调用我们上面自定义的方法
JobDetail object = heartbeat.getObject();
cronTriggerFactoryBean.setJobDetail(object);
//10秒执行一次心跳方法
cronTriggerFactoryBean.setCronExpression("0/10 * * * * ? ");
return cronTriggerFactoryBean;
}
//注册一个统一调度工厂
@Bean
public SchedulerFactoryBean schedulerFactoryBean(@Autowired CronTriggerFactoryBean cronTriggerFactoryBean){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
//注入上面触发器
schedulerFactoryBean.setTriggers(cronTriggerFactoryBean.getObject());
return schedulerFactoryBean;
}
}
cron表达式
上面的入门案例中我们指定了一个表达式:0/10 * * * * ?
这种表达式称为cron表达式,通过cron表达式可以灵活的定义出符合要求的程序执行的时间。本小节我
们就来学习一下cron表达式的使用方法。如下图:
cron表达式分为七个域,之间使用空格分隔。其中最后一个域(年)可以为空。每个域都有自己允许的
值和一些特殊字符构成。使用这些特殊字符可以使我们定义的表达式更加灵活。
下面是对这些特殊字符的介绍:
逗号(,):指定一个值列表,例如使用在月域上1,4,5,7表示1月、4月、5月和7月
横杠(-):指定一个范围,例如在时域上3-6表示3点到6点(即3点、4点、5点、6点)
星号(*):表示这个域上包含所有合法的值。例如,在月份域上使用星号意味着每个月都会触发
斜线(/):表示递增,例如使用在秒域上0/15表示每15秒
问号(?):只能用在日和周域上,但是不能在这两个域上同时使用。表示不指定
井号(#):只能使用在周域上,用于指定月份中的第几周的哪一天,例如6#3,意思是某月的第三个
周五 (6=星期五,3意味着月份中的第三周)
L:某域上允许的最后一个值。只能使用在日和周域上。当用在日域上,表示的是在月域上指定的月份
的最后一天。用于周域上时,表示周的最后一天,就是星期六
W:W 字符代表着工作日 (星期一到星期五),只能用在日域上,它用来指定离指定日的最近的一个工作
日
cron表达式在线生成网站
前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些cron表达式在线生
成器来根据我们的需求生成表达式即可。
cron表达式在线生成
QuartzHelloWorld
package com.fs.regularwork;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
自定义的普通类,让Quartz 通过反射来定时执行这个方法
*/
public class QuartzHelloWorld {
//编写定时执行的方法,注意要是public的
public void quartzTest(){
System.out.println("02:HelloWorld_Quartz"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));
}
}
QuartzHelloWorld02
package com.fs.regularwork;
import java.text.SimpleDateFormat;
import java.util.Date;
/*
自定义的普通类,让Quartz 通过反射来定时执行这个方法
*/
public class QuartzHelloWorld02 {
//编写定时执行的方法,注意要是public的
public void quartzTest02(){
System.out.println("01:HelloWorld_Quartz"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));
}
}
TestQuartz测试类
package com.fs.regularwork;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
测试Quartz
*/
public class TestQuartz {
public static void main(String[] args) {
//只有创建了spring的容器,定时器就会去反射通过我们xml配置的cron表达式指定的时间去调用我们配置的方法
new ClassPathXmlApplicationContext("classpath:applicationContext-jobs.xml");
}
}
运行结果