springBoot下使用quartz定时任务;动态修改任务执行时间

先上依赖

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

新建一个自己的Job类,待会触发器执行的就是这个类重写的QuartzJobBean下的executeInternal方法

里面可以通过spring注入业务类,这样就可以执行业务逻辑了

package com.fchan.layui.quzrtzForSpring;

import com.fchan.layui.quartz.TestJobDetailService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;

@Component
public class HiJob extends QuartzJobBean {
	
	//自己的业务类,我在里面就打印输出了一下字符串:"开始处理业务了"
    @Autowired
    private TestJobDetailService testJobDetailService;


    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        testJobDetailService.doJob();
        System.out.println("    Hi! :" + context.getJobDetail().getKey());
    }
}

配置类,配置Jobdetail(配置执行哪个Job)和Trigger触发器(定义cron的bean)

Jobdetail->Job->业务类

package com.fchan.layui.quzrtzForSpring;

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class QuzrtzForSpringConfig {

    @Bean
    public JobDetail myJobDetail(){
        JobDetail jobDetail = JobBuilder.newJob(HiJob.class)
                //任务名和任务组别
                .withIdentity("myJobName","myJobGroup")
                //JobDataMap可以给任务execute传递参数
                .usingJobData("job_param","job_param1")
                .storeDurably()
                .build();
        return jobDetail;
    }

    @Bean
    public Trigger myTrigger(){
        Trigger trigger = TriggerBuilder.newTrigger()
                .forJob(myJobDetail())
                //触发器名,触发器所在组
                .withIdentity("myTrigger1","myTriggerGroup1")
                .usingJobData("job_trigger_param","job_trigger_param1")
                .startNow()
                //.withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(5).repeatForever())
                .withSchedule(CronScheduleBuilder.cronSchedule("0/3 * * * * ? 2020"))
                .build();
        return trigger;
    }

}

然后跑起来就可以在控制台看到业务类中打印输出的内容了
在这里插入图片描述

动态修改任务执行时间

动态执行的时候就不能直接写死时间了。
quzrtz中的定时任务分为这几大块:

  • jobDetail:描述实际执行任务的class
  • trigger:触发器,定义执行时间
  • scheduler:关联触发器和任务

所以要动态修改时间,就要修改触发器中的时间,然后重新关联任务。

代码demo

实际执行任务class

package com.fchan.business.cron;

import com.fchan.business.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import javax.annotation.Resource;
import java.time.LocalDateTime;

@Slf4j
public class MailTask extends QuartzJobBean {

    @Resource
    ISysUserService iSysUserService;

    @Override
    protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
        log.info("开始执行邮件任务" + LocalDateTime.now());
    }
}
package com.fchan.business.cron;

import lombok.Data;

/**
 * 定义时间和实际执行任务的class
 */

@Data
public class QuartzBean {

    /** 任务id */
    private String  id;

    /** 任务名称 */
    private String jobName;

    /** 任务执行类 */
    private String jobClass;

    /** 任务状态 启动还是暂停*/
    private Integer status;

    /** 任务运行时间表达式 */
    private String cronExpression;


}

新增/暂停/修改/删除定时任务

package com.fchan.business.utils;

import com.fchan.business.cron.QuartzBean;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.Objects;

@Slf4j
public class CronUtil {


    /**
     * 创建一个定时任务
     * @param scheduler
     * @param quartzBean
     */
    public static void createScheduleJob(Scheduler scheduler, QuartzBean quartzBean){
        try {

            //反射获取实际执行任务的class
            Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(quartzBean.getJobClass());

            //构建任务信息,实际执行的任务类
            JobDetail jobDetail = JobBuilder
                                        .newJob(jobClass)
                                        //jobName需要保证唯一
                                        .withIdentity(quartzBean.getJobName())
                                        .build();

            //设置执行方式为cron
            CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder
                    .cronSchedule(quartzBean.getCronExpression())
                    //阻塞的过期任务立即执行
                    .withMisfireHandlingInstructionFireAndProceed();

            //关联触发器和cron执行器
            CronTrigger cronTrigger = TriggerBuilder
                    .newTrigger()
                    .withIdentity(quartzBean.getJobName())
                    .withSchedule(cronScheduleBuilder)
                    .build();



            //检查任务是否过期
            Date nextFireTime = cronTrigger.getFireTimeAfter(new Date());
            if(Objects.isNull(nextFireTime)){
                log.info("任务已过期,job:{}", quartzBean);
                return;
            }

            //按照cron时间开始运行任务,并且时间已经过期则创建时会报错,提示过期
            scheduler.scheduleJob(jobDetail, cronTrigger);
        } catch (ClassNotFoundException | SchedulerException e) {
            throw new RuntimeException(e);
        }

    }


    /**
     * 更新当前正在运行的任务的cron时间
     * @param scheduler
     * @param quartzBean
     */
    public static void updateJobTime(Scheduler scheduler, QuartzBean quartzBean){

        //build触发key
        TriggerKey triggerKey = TriggerKey.triggerKey(quartzBean.getJobName());

        String cronExpression = quartzBean.getCronExpression();

        //build新的cron执行器
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);

        try {

            //获取当前正在运行的触发器
            CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);

            if(Objects.isNull(cronTrigger)){
                log.error("未找到触发器,jobName:{}", quartzBean.getJobName());
                return;
            }

            //根据新的执行器重新关联触发器
            cronTrigger = cronTrigger
                                .getTriggerBuilder()
                                .withIdentity(triggerKey)
                                .withSchedule(cronScheduleBuilder)
                                .build();

            log.info("重置了任务时间" + LocalDateTime.now());

            //重置对应的job
            scheduler.rescheduleJob(triggerKey, cronTrigger);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 暂停任务
     * @param scheduler
     * @param jobName
     */
    public static void pauseJob(Scheduler scheduler, String jobName){
        JobKey jobKey = JobKey.jobKey(jobName);

        try {
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 恢复暂停的任务
     * @param scheduler
     * @param jobName
     */
    public static void resumeJob(Scheduler scheduler, String jobName){
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 删除任务
     * @param scheduler
     * @param jobName
     */
    public static void deleteJob(Scheduler scheduler, String jobName){
        JobKey jobKey = JobKey.jobKey(jobName);
        try {
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
    }


}
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot使用Quartz实现动态定时任务可以分为以下几个步骤: 1. 添加依赖 在`pom.xml`文件中添加Quartz依赖: ```xml <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.2</version> </dependency> ``` 2. 配置Quartz 在`application.properties`中添加Quartz的配置: ``` # 配置Quartz的JobStore org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.StdJDBCDelegate org.quartz.jobStore.tablePrefix = QRTZ_ org.quartz.jobStore.isClustered = false # 配置Quartz的线程池 org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool org.quartz.threadPool.threadCount = 10 org.quartz.threadPool.threadPriority = 5 # 配置Quartz的数据源 org.quartz.dataSource.myDS.driver = com.mysql.jdbc.Driver org.quartz.dataSource.myDS.URL = jdbc:mysql://localhost:3306/quartz org.quartz.dataSource.myDS.user = root org.quartz.dataSource.myDS.password = root org.quartz.dataSource.myDS.maxConnections = 5 org.quartz.dataSource.myDS.validationQuery = select 0 ``` 3. 创建Job 创建一个继承`org.quartz.Job`接口的类,用于执行定时任务的逻辑代码。 ```java public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 执行定时任务逻辑 } } ``` 4. 创建Trigger 创建一个继承`org.quartz.Trigger`接口的类,用于设置定时任务的触发器,例如定时任务执行时间执行频率等。 ```java public class MyTrigger implements Trigger { @Override public Date getNextFireTime() { // 设置下一次执行时间 return null; } @Override public Date getPreviousFireTime() { // 获取上一次执行时间 return null; } @Override public void setNextFireTime(Date nextFireTime) { // 设置下一次执行时间 } @Override public void setPreviousFireTime(Date previousFireTime) { // 设置上一次执行时间 } // 其他方法省略... } ``` 5. 创建Scheduler 创建一个`org.quartz.Scheduler`实例,用于管理定时任务执行。 ```java public class MyScheduler { private Scheduler scheduler; public MyScheduler(Scheduler scheduler) { this.scheduler = scheduler; } // 添加定时任务 public void addJob(JobDetail jobDetail, Trigger trigger) throws SchedulerException { scheduler.scheduleJob(jobDetail, trigger); } // 删除定时任务 public void deleteJob(JobKey jobKey) throws SchedulerException { scheduler.deleteJob(jobKey); } // 修改定时任务 public void updateJob(TriggerKey triggerKey, Trigger newTrigger) throws SchedulerException { scheduler.rescheduleJob(triggerKey, newTrigger); } // 启动定时任务 public void start() throws SchedulerException { scheduler.start(); } // 关闭定时任务 public void shutdown() throws SchedulerException { scheduler.shutdown(); } } ``` 6. 创建动态定时任务 创建一个类,用于动态添加、删除、修改定时任务。 ```java @Service public class DynamicJobService { @Autowired private Scheduler scheduler; // 添加定时任务 public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class<? extends Job> jobClass, String cronExpression) throws SchedulerException { JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build(); CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(triggerName, triggerGroupName).withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build(); scheduler.scheduleJob(jobDetail, trigger); } // 删除定时任务 public void deleteJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName) throws SchedulerException { scheduler.pauseTrigger(new TriggerKey(triggerName, triggerGroupName)); scheduler.unscheduleJob(new TriggerKey(triggerName, triggerGroupName)); scheduler.deleteJob(new JobKey(jobName, jobGroupName)); } // 修改定时任务 public void updateJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cronExpression) throws SchedulerException { CronTrigger trigger = (CronTrigger) scheduler.getTrigger(new TriggerKey(triggerName, triggerGroupName)); trigger = trigger.getTriggerBuilder().withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build(); scheduler.rescheduleJob(new TriggerKey(triggerName, triggerGroupName), trigger); } // 暂停定时任务 public void pauseJob(String jobName, String jobGroupName) throws SchedulerException { scheduler.pauseJob(new JobKey(jobName, jobGroupName)); } // 恢复定时任务 public void resumeJob(String jobName, String jobGroupName) throws SchedulerException { scheduler.resumeJob(new JobKey(jobName, jobGroupName)); } } ``` 7. 测试 ```java @Service public class TestService { @Autowired private DynamicJobService dynamicJobService; public void test() throws SchedulerException { // 添加定时任务 dynamicJobService.addJob("job1", "group1", "trigger1", "group1", MyJob.class, "0/5 * * * * ?"); // 修改定时任务 dynamicJobService.updateJob("job1", "group1", "trigger1", "group1", "0/10 * * * * ?"); // 暂停定时任务 dynamicJobService.pauseJob("job1", "group1"); // 恢复定时任务 dynamicJobService.resumeJob("job1", "group1"); // 删除定时任务 dynamicJobService.deleteJob("job1", "group1", "trigger1", "group1"); } } ``` 以上就是使用Spring BootQuartz实现动态定时任务的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值