企业级任务调度框架Quartz

希望成为一个面对任何事情都能从容面对的人                                                                        

Quartz是什么

  • 开源的企业级任务调度框架
  • 在某个时间点做某件事情,核心是以时间为关注点,即在一个特定的时间点,系统执行指定的一个操作

Quartz能干什么

  • 场景1

每天晚上12点定时备份数据库里重要的数据

  • 场景2

会员到期提醒,在你会员快要到期的时候,给你发邮件提醒你会员到期进行续费

Quartz核心概念

  • 任务(job):就是执行的工作内容(业务逻辑)。Quartz提供Job接口来支持任务定义。
  • 触发器(Trigger):定义触发Job执行的时间触发规则(执行时间点)。Quartz提供Trigger类及其子类来支持触发器功能。
  • 调度器(Scheduler):Quartz提供Scheduler接口(start),将工作任务和触发器进行绑定,保证任务可以在正确的时间执行。

Quartz官网

传送门

Quartz的HelloWorld程序

 1.引入pom坐标

<dependency>                  
    <groupId>org.quartz-scheduler</groupId>                  
    <artifactId>quartz</artifactId>                  
    <version>2.3.2</version>          
</dependency>

2. 定义要执行的任务

import org.quartz.Job;  
import org.quartz.JobExecutionContext;  
import org.quartz.JobExecutionException;   
import java.util.Date;   
public class MyJob implements Job {          
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {                 
        System.out.println("HelloWorld:" + new Date());          
    }  
}

3. 创建触发任务相关的schedule

import org.quartz.*;  
import org.quartz.impl.StdSchedulerFactory;   
public class TestMyJob {          
    public static void main(String[] args) {                  
        // 创建jobDetail,并把要执行的任务放进去                  
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)
                              .withIdentity("job1", "group1")
                              .build();                   
        // 创建trigger                  
        Trigger trigger = TriggerBuilder.newTrigger()
                          .withIdentity("trigger1", "trigger1")
                          .startNow()                 
                          .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInSeconds(1).repeatForever())
                          .build();                   
        // 创建scheduler                  
        try {                          
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();                                  
            scheduler.scheduleJob(jobDetail, trigger);                          
            scheduler.start();                  
        } catch (Exception e) {                          
            e.printStackTrace();                  
        }          
    }  
}

4. 运行结果

HelloWorld:Tue Aug 29 21:43:42 CST 2023  
HelloWorld:Tue Aug 29 21:43:43 CST 2023  
HelloWorld:Tue Aug 29 21:43:44 CST 2023  
HelloWorld:Tue Aug 29 21:43:45 CST 2023  
HelloWorld:Tue Aug 29 21:43:46 CST 2023  
HelloWorld:Tue Aug 29 21:43:47 CST 2023  
HelloWorld:Tue Aug 29 21:43:48 CST 2023  
HelloWorld:Tue Aug 29 21:43:49 CST 2023  
HelloWorld:Tue Aug 29 21:43:50 CST 2023  
HelloWorld:Tue Aug 29 21:43:51 CST 2023

Quartz架构图

Quartz的上下文对象

使用usingJobData携带需要传输的数据

public class TestMyJob {          
    public static void main(String[] args) {                  
        // 创建jobDetail,并把要执行的任务放进去                  
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)                 
                              .withIdentity("job1", "group1")             
                              .usingJobData("id", "1234567")             
                              .usingJobData("name", "张三")             
                              .build();                  
        // 创建trigger                  
        Trigger trigger = TriggerBuilder.newTrigger()                              
                          .withIdentity("trigger1", "trigger1")                              
                          .startNow()  
                          .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInSeconds(1).repeatForever())                              
                          .build();                   
        // 创建scheduler                  
        try {                          
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();                              
            scheduler.scheduleJob(jobDetail, trigger);                          
            scheduler.start();                  
        } catch (Exception e) {                          
            e.printStackTrace();                  
        }          
    }  
}

在执行任务的时候获取

public class MyJob implements Job {          
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {                  
        JobDetail jobDetail = jobExecutionContext.getJobDetail();                      
        JobDataMap jobDataMap = jobDetail.getJobDataMap();                  
        Object id = jobDataMap.get("id");                  
        Object name = jobDataMap.get("name");                  
        System.out.println("上面传过来的id: " + id);                  
        System.out.println("上面传过来的name: " + name);          
    }  
}

 运行结果

上面传过来的id: 1234567  
上面传过来的name: 张三

控制开始时间和结束时间

startAt():任务延迟多久开始执行  

endAt():任务执行多久

public class TestMyJob {          
    public static void main(String[] args) {                  
        // 创建jobDetail,并把要执行的任务放进去                  
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)                                  
                              .withIdentity("job1", "group1")                              
                              .usingJobData("id", "1234567")                                  
                              .usingJobData("name", "张三")                                  
                              .build();                   
        Date startDate = new Date();                  
        startDate.setTime(startDate.getTime() + 5000);                  
        Date endDate = new Date();                  
        endDate.setTime(startDate.getTime() + 5000);                   
        // 创建trigger                  
        Trigger trigger = TriggerBuilder.newTrigger()                              
                          .withIdentity("trigger1", "trigger1")                              
                          .startAt(startDate)                              
                          .endAt(endDate)                 		    
                          .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                          .withIntervalInSeconds(1).repeatForever())                                      
                          .build();                   
        // 创建scheduler                  
        try {                          
                Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();                                  
                scheduler.scheduleJob(jobDetail, trigger);                              
                scheduler.start();                  
        } catch (Exception e) {                         
            e.printStackTrace();                  
        }          
    }  
}

延迟五秒开始,任务只执行五秒

CronTrigger触发器

  • SimpleTrigger:应用场景(固定时间间隔的调度任务),使用方式(通过设置触发器的属性:开始时间、结束时间、重复次数、重复间隔等)
  • CronTrigger:应用场景(指定时间点的调度任务,例如每天凌晨两点执行一次),使用方式(通过Cron定义表达式)

CronTrigger允许用户更准确地控制任务的运行日期和时间,而不仅仅是定义工作的频度。

使用示例

public class TestMyJob {          
    public static void main(String[] args) {                  
        // 创建jobDetail,并把要执行的任务放进去                  
        JobDetail jobDetail = JobBuilder.newJob(MyJob.class)                                  
                              .withIdentity("job1", "group1")                              
                              .build();                   
        // 创建trigger                  
        Trigger trigger = TriggerBuilder.newTrigger()                              
                          .withIdentity("trigger1", "trigger1")                                  
                          .withSchedule(CronScheduleBuilder.cronSchedule("0 39 22 * * ?"))                                  
                          .build();                   
        // 创建scheduler                  
        try {                          
            Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();                          
            scheduler.scheduleJob(jobDetail, trigger);                              
            scheduler.start();                  
        } catch (Exception e) {                          
            e.printStackTrace();                  
        }          
    }  
}

SpringBoot整合Quartz完整使用流程

1. 引用依赖,2.3.2稳定

<dependencies>       
    ...       
    <dependency>           
        <groupId>org.quartz-scheduler</groupId>           
        <artifactId>quartz</artifactId>           
        <version>2.3.2</version>       
    </dependency>       
    ...   
</dependencies>

2.Quartz配置类

import org.quartz.Scheduler; 
import org.quartz.SchedulerException; 
import org.quartz.impl.StdSchedulerFactory; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration;  
@Configuration 
public class QuartzConfig {     
    @Bean     
    public Scheduler scheduler() throws SchedulerException {         
        return StdSchedulerFactory.getDefaultScheduler();     
    } 
}

3.创建Quartz任务类

import org.quartz.Job;   
import org.quartz.JobExecutionContext;   
import org.quartz.JobExecutionException;   
import org.springframework.stereotype.Component;      
@Component   
public class MyQuartzJob implements Job {       
    @Override       
    public void execute(JobExecutionContext context) throws JobExecutionException {               
        System.out.println("Quartz任务执行!");       
    }   
}

4.创建一个Quartz工具类,用于添加、暂停、删除、修改任务等操作。

import org.quartz.*; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service;  
@Service 
public class QuartzUtils {     
    @Autowired     
    private Scheduler scheduler;      
    public void addJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {         
        scheduler.scheduleJob(jobDetail, trigger);     
    }      

    public void pauseJob(JobKey jobKey) throws SchedulerException {             
        scheduler.pauseJob(jobKey);     
    }      

    public void resumeJob(JobKey jobKey) throws SchedulerException {         
        scheduler.resumeJob(jobKey);     
    }      

    public void deleteJob(JobKey jobKey) throws SchedulerException {             
        scheduler.deleteJob(jobKey);     
    }     

    public void updateJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException {         
        scheduler.rescheduleJob(trigger.getKey(), trigger);     
    } 
}

5. 创建Jobdetails

import org.quartz.*; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
import com.example.util.QuartzUtils;  
@Component 
public class MyQuartzJobDetail {     
    @Autowired     
    private QuartzUtils quartzUtils;      
    public void addJob() throws SchedulerException {         
        // 创建JobDetail实例,保存关于要执行的job的信息。这里使用了刚刚创建的MyQuartzJob。             
        JobDetail jobDetail = JobBuilder.newJob(MyQuartzJob.class)                     
                              .withIdentity("myQuartzJob", "group1") // 第一个参数是名称,第二个参数是组名,方便进行管理。                 
                              .build();         
        // 创建Trigger实例,告诉scheduler何时开始执行job。这里指定了立即执行。         
        Trigger trigger = TriggerBuilder.newTrigger()                 
                          .withIdentity("myQuartzTrigger", "group1") // 名称和组名                 .startNow() // 立即开始执行任务。                 
                          .build();         
        // 将job与trigger关联起来。         
        quartzUtils.addJob(jobDetail, trigger); // 使用前面创建的工具类方法。     
}
工具类使用示例

1.addJob方法:

QuartzUtils quartzUtils = new QuartzUtils();  
  
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)  
        .withIdentity("myQuartzJob", "group1")  
        .build();  
  
Trigger trigger = TriggerBuilder.newTrigger()  
        .withIdentity("myQuartzTrigger", "group1")  
        .startNow()  
        .build();  
  
quartzUtils.addJob(jobDetail, trigger);

2.pauseJob方法:

QuartzUtils quartzUtils = new QuartzUtils();  
  
JobKey jobKey = JobKey.jobKey("myQuartzJob", "group1");  
quartzUtils.pauseJob(jobKey);

3.resumeJob方法:

QuartzUtils quartzUtils = new QuartzUtils();  
  
JobKey jobKey = JobKey.jobKey("myQuartzJob", "group1");  
quartzUtils.resumeJob(jobKey);

4.deleteJob方法:

QuartzUtils quartzUtils = new QuartzUtils();  
  
JobKey jobKey = JobKey.jobKey("myQuartzJob", "group1");  
quartzUtils.deleteJob(jobKey);

5.updateJob方法:

QuartzUtils quartzUtils = new QuartzUtils();  
  
JobDetail jobDetail = JobBuilder.newJob(MyJob.class)  
        .withIdentity("myQuartzJob", "group1")  
        .build();  
  
Trigger trigger = TriggerBuilder.newTrigger()  
        .withIdentity("myQuartzTrigger", "group1")  
        .startNow()  
        .build();  
  
quartzUtils.updateJob(jobDetail, trigger);
修改一个组下的所有定时任务的执行时间
  1. 获取该组下的所有定时任务。
  2. 遍历每个定时任务,并修改它们的执行时间。
  3. 使用QuartzUtils工具类的updateJob方法更新每个任务的执行时间。
import org.quartz.JobKey;  
import org.quartz.SchedulerException;  
import org.quartz.TriggerKey;  
import org.quartz.impl.matchers.GroupMatcher;  
  
// 获取所有组名为"group1"的定时任务  
GroupMatcher<JobKey> groupMatcher = GroupMatcher.groupEquals("group1");  
List<TriggerKey> triggerKeys = scheduler.getTriggerKeys(groupMatcher);   
  
for (TriggerKey triggerKey : triggerKeys) {  
    try {  
        // 获取定时任务对应的触发器  
        Trigger trigger = scheduler.getTrigger(triggerKey);  
          
        // 修改触发器的执行时间(例如,将执行时间改为每天上午9点)  
        Date newStartDate = DateBuilder.futureDate(9, IntervalUnit.HOUR);  
        trigger = TriggerBuilder.newTrigger().withIdentity(triggerKey)  
                .startAt(newStartDate).build();  
          
        // 使用QuartzUtils工具类更新触发器的执行时间  
        quartzUtils.updateJob(null, trigger);  
    } catch (SchedulerException e) {  
        e.printStackTrace();  
    }  
}

猜你喜欢

转载自blog.csdn.net/2301_76354366/article/details/132647879