quartz官网文档:http://www.quartz-scheduler.org/
quartz是一个定时调度的框架,属于比较早期的产品,现在市面上流行的xxl-Job,elastic-Job分布式调度框架都是基于该产品。虽然很多人说quartz的使用不是很方便,api不人性化。但是学习quartz还是有助于我们理解其他的框架。并且市面上依旧有大量的项目正在使用quartz。
Quartz能够与spring完美整合,使用Quartz可以开发多个定时任务,每个任务都可以单独指定触发的时间频率。例如每周日下午五点执行一次。
1、运行定时任务、发送定时消息:如每天早上七点发送消息、定时生成报表、自动结账、自动更新静态数据、定时的数据备份。
2、定义周期任务:本质还是定时任务,在定时的基础上设置成周期任务。
3、分布式和集群能力:Quartz支持集群和分布式环境,
4、任务优先级和调度:Quartz允许你设置任务的优先级,并且可以基于优先级调度任务。这意味着,如果两个任务同时可用,那么优先级较高的任务会优先执行。
5、任务失败重试:Quartz可以配置任务失败时候的重试策略。
6、任务依赖关系:Quartz允许任务之间建立依赖关系,这使得任务调度更加灵活和可配置。
从图中可以看出QuartZ主要有四大核心:
1、调度器(Scheduler):任务运行的容器或地点。
2、任务(JobDetail):定时任务本身的消息,如任务的名称,组等。
3、触发器(Trigger):任务触发规则,例如:每小时触发一次等。
4、任务:Job(任务的具体执行内容)
1、Scheduler详解:调度器,Quartz独立的运行容器。从图中可以看出,触发器(Trigger)和任务(JobDetail)都会被注册到Scheduler中。一个job可以被多个jobDetail装载,一个jobDetail可以被多个trigger来配置规则,但一个trigger只能装载一个jobDetail。当Trigger被触发时,对应的job就会执行。一个Job可以对应多个Trigger,但一个Trigger只能对应一个Job。任务:JobDetail。
2、触发器详解:Trigger,描述触发job执行的时间规则,实现类包括
SimpleTrigger简单触发器:实现固定时刻或固定间隔
CronTrigger触发器:基于Cron表达式触发器、
CalendarIntervalTrigger基于日历的触发器:如每个月的1 号15号执行。
DailyTimeIntervalTrigger基于日期的触发器,每天的固定时间
?其中CronTrigger可以通过cron表示式定义出复杂的调度方案,表达式使用地址如下:
?? 在线Cron表达式生成器
3、JobDetail详解:当Trigger被触发时,Quartz创建一个Job实例,对应的job就会执行。JobDetail就是用来描述Job实现类以及相关静态信息,比如任务在scheduler中的组名等信息。
4、Job详解:需要实现QuartzJobBean类重写executeInternal方法,在这个方法中创建具体的任务细节。
核心包:spring-boot-starter-quartz
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>quartzdemo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quartzdemo1</name>
<description>quartzdemo1</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<builder>paketobuildpacks/builder-jammy-base:latest</builder>
</image>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
在配置类中配置触发器(Trigger)和任务(JobDetail)
但是此时的trigger没有设置时间规则,只会触发一次。
@Configuration
public class QuartzJobConfig {
@Bean
public JobDetail jobDetail(){
JobDetail detail= JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("job1","group1")
.storeDurably()//设置Job持久化
//设置job数据
.usingJobData("username","xiaochun")
.usingJobData("useraddr","安徽合肥")
.build();
return detail;
}
//创建触发器,触发实例
@Bean
public Trigger trigger(){
Trigger trigger= TriggerBuilder.newTrigger()
.forJob(jobDetail())
.withIdentity("trigger1","group1")
.startNow()
.build();
return trigger;
}
}
@Slf4j
public class MyQuartzJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
//执行的具体内容
log.info("=========quartz具体内容============");
}
}
如下图项目启动的时候,任务启动,但是只会启动一次。
在上面案例的基础上配置时间规则,如每5秒执行一次。
表达式的使用可以使用官网中直接生成。
在线Cron表达式生成器:在线Cron表达式生成器
常用案例如下:
常用cron表达式例子
??(1)0/2 * * * * ????表示每2秒 执行任务
??(1)0 0/2 * * * ?????表示每2分钟 执行任务
??(1)0 0 2 1 * ????表示在每月的1日的凌晨2点调整任务
??(2)0 15 10 ? * MON-FRI?? 表示周一到周五每天上午10:15执行作业
??(3)0 15 10 ? 6L 2002-2006?? 表示2002-2006年的每个月的最后一个星期五上午10:15执行作
??(4)0 0 10,14,16 * * ????每天上午10点,下午2点,4点?
??(5)0 0/30 9-17 * * ??? 朝九晚五工作时间内每半小时?
??(6)0 0 12 ? * WED?? ?表示每个星期三中午12点?
??(7)0 0 12 * * ????每天中午12点触发?
??(8)0 15 10 ? * * ???每天上午10:15触发?
??(9)0 15 10 * * ??? ? 每天上午10:15触发?
??(10)0 15 10 * * ??? ?每天上午10:15触发?
??(11)0 15 10 * * ? 2005?? ?2005年的每天上午10:15触发?
??(12)0 * 14 * * ??? ? 在每天下午2点到下午2:59期间的每1分钟触发?
??(13)0 0/5 14 * * ??? ?在每天下午2点到下午2:55期间的每5分钟触发?
??(14)0 0/5 14,18 * * ??? ? 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发?
??(15)0 0-5 14 * * ??? ?在每天下午2点到下午2:05期间的每1分钟触发?
??(16)0 10,44 14 ? 3 WED?? ?每年三月的星期三的下午2:10和2:44触发?
??(17)0 15 10 ? * MON-FRI?? ?周一至周五的上午10:15触发?
??(18)0 15 10 15 * ??? ?每月15日上午10:15触发?
??(19)0 15 10 L * ??? ?每月最后一日的上午10:15触发?
??(20)0 15 10 ? * 6L?? ?每月的最后一个星期五上午10:15触发?
??(21)0 15 10 ? * 6L 2002-2005?? 2002年至2005年的每月的最后一个星期五上午10:15触发?
??(22)0 15 10 ? * 6#3?? 每月的第三个星期五上午10:15触发
@Configuration
public class QuartzJobConfig {
//每隔5秒执行一次
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule("0/5 * * * * ?");
@Bean
public JobDetail jobDetail(){
JobDetail detail= JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("job1","group1")
.storeDurably()//设置Job持久化
//设置job数据
.usingJobData("data","自定义数据")
.build();
return detail;
}
//创建触发器,触发实例
@Bean
public Trigger trigger(){
Trigger trigger= TriggerBuilder.newTrigger()
//关联jobDetail
.forJob(jobDetail())
.withIdentity("trigger1","group1")
.withSchedule(cronScheduleBuilder)
.startNow()
.build();
return trigger;
}
}
输出结果
从结果可以看出:任务每隔五秒执行一次。
如果时间规则没有name复杂,可以使用SimpleScheduleBuilder配置简单的时间规则。
withIntervalInSeconds(3):时间规则为秒,还有小时,分钟,毫秒单位等。
@Configuration
public class QuartzJobConfig {
@Bean
public JobDetail jobDetail(){
JobDetail detail= JobBuilder.newJob(MyQuartzJob.class)
.withIdentity("job1","group1")
.storeDurably()//设置Job持久化
//设置job数据
.usingJobData("username","xiaochun")
.usingJobData("useraddr","安徽合肥")
.build();
return detail;
}
//创建触发器,触发实例
@Bean
public Trigger trigger(){
Trigger trigger= TriggerBuilder.newTrigger()
//关联jobDetail
.forJob(jobDetail())
.withIdentity("trigger1","group1")
.withSchedule(SimpleScheduleBuilder.simpleSchedule()
//执行间隔
.withIntervalInSeconds(3)
//执行次数
.repeatForever())
.startNow()
.build();
return trigger;
}
}
输出结果
也就是获取JobDetail中通过//设置job数据.usingJobData("username","xiaochun")设置的参数,
通过context.getJobDetail().getJobDataMap().get("username")可以获取到。
@Slf4j
public class MyQuartzJob extends QuartzJobBean {
??? @Override
??? protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
??????? //执行的具体内容
??????? log.info("=========quartz具体内容============");
??????? System.out.println(context.getJobInstance());
??????? System.out.println(context.getJobDetail().getJobDataMap().get("username"));
??? }
}
输出结果:
源码下载:https://download.csdn.net/download/tangshiyilang/88632313
@Scheduled?? 任务调度执行 注解用该注解修饰方法
@EnableScheduling? 开启任务调度? 需要配置在启动类上?
核心类:spring-boot-starter-quartz
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.txc</groupId>
<artifactId>quartzannotationdemo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>quartzannotationdemo1</name>
<description>quartzannotationdemo1</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
@EnableScheduling:开启任务调度
@SpringBootApplication
@EnableScheduling
public class Quartzannotationdemo1Application {
public static void main(String[] args) {
SpringApplication.run(Quartzannotationdemo1Application.class, args);
}
}
@Component
public class QuartzTimedTask {
//每5s执行一次
@Scheduled(cron = "0/5 * * * * ?")
public void process(){
System.out.println("======process======"+new Date());
}
}
结果输出: