SpringBoot下用Quartz实现动态配置定时任务

该博客展示了如何在Spring Boot应用中使用Quartz Scheduler来创建和管理定时任务。配置了Quartz的依赖,并通过配置类启动调度器。任务类`StartQuartzJob`负责根据数据库中的任务配置动态创建和更新定时任务,而`ReadDbJob`则作为实际执行的任务。通过CronTrigger和SimpleTrigger设置任务的执行周期和时间。
摘要由CSDN通过智能技术生成

相关概念就不介绍了,直接上代码。

pom.xml配置

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

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

Quartz配置类

@Configuration
public class QuartzConfig {

    private final Scheduler scheduler;

    public QuartzConfig(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    @Bean(name = "scheduler")
    public Scheduler setScheduler() {
        return scheduler;
    }
}

启动Quartz配置类

@Configuration
public class StartQuartz implements CommandLineRunner {

    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Override
    public void run(String... args) throws Exception {
        // 启动调度器
        scheduler.start();
        // 定时执行任务
        JobDetail exportJob = JobBuilder.newJob(StartQuartzJob.class).withIdentity(StartQuartzJob.class.getName(), "startTask").build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/10 * * * * ?");
        CronTrigger exportTrigger = TriggerBuilder.newTrigger().withIdentity(StartQuartzJob.class.getName(), "startTask")
                .withSchedule(scheduleBuilder).build();
        try {
            scheduler.scheduleJob(exportJob, exportTrigger);
        } catch (SchedulerException e) {
            System.out.println("创建定时任务失败" + e);
            throw new Exception("创建定时任务失败");
        }
    }

}

Job任务类


public class StartQuartzJob extends QuartzJobBean {
    @Resource(name = "scheduler")
    private Scheduler scheduler;

    @Autowired
    private TaskAdo taskAdo;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date()) + ":[StartQuartzJob]:"+jobExecutionContext.getJobDetail().getKey().toString());
        String jobName = "";
        String jobCron = ""; 
        String taskGroup = "";
		String taskType = "";
        Long dtID = 0L;
        JobDetail exportJob = null;
        Date onceTime = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JobKey jobKey = null;
        try {
            List<Map<String, Object>> mapTaskCronList = null;

            // 查询任务,Cron 
            mapTaskCronList = taskAdo.getAllTaskCron(); 
            for (Map mapTaskCron : mapTaskCronList) {
                taskGroup = mapTaskCron.get("task_group").toString();
                jobCron = mapTaskCron.get("cron") == null ? "" : mapTaskCron.get("cron").toString(); 
                jobName = mapTaskCron.get("task_name").toString();
				taskType = mapTaskCron.get("task_type").toString();
                jobKey = JobKey.jobKey(jobName, taskGroup);
                dtID = Long.parseLong(mapTaskCron.get("dt_id").toString());

                // 判断任务是否已经存在
                if (!scheduler.checkExists(jobKey)) {
                    // 添加一个任务 
                    exportJob = JobBuilder.newJob(ReadDbJob.class).withIdentity(jobName, taskGroup).build();
  
                    // 根据 任务类型创建不同触发器
                    if ("REPT".equals(taskType)) {
						// cron 表达式重复执行触发器
                        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobCron);
                        CronTrigger exportTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, taskGroup).withSchedule(scheduleBuilder).build();
                        scheduler.scheduleJob(exportJob, exportTrigger);
                    } else {
						// 指定时间点单次执行
                        onceTime = sdf.parse(mapTaskCron.get("one_time").toString().replace("T", " "));
                        SimpleTrigger simpleTrigger = TriggerBuilder.newTrigger().withIdentity(jobName, taskGroup).startAt(onceTime)
                                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
								.withIntervalInSeconds(10) // 指定时间点滞后多少秒
								.withRepeatCount(0)) // 重复执行多少次
								.build();
                        scheduler.scheduleJob(exportJob, simpleTrigger);
                    }
                } else { 
                    // 只有重复执行的才需要的才会有变更cron表达式重复条件
                    if ("REPT".equals(taskType)) {
                        // 根据jobName获取TriggerKey,CronTrigger
                        TriggerKey currTriggerKey = TriggerKey.triggerKey(jobName, taskGroup);
                        CronTrigger currTrigger = (CronTrigger) scheduler.getTrigger(currTriggerKey);
                        //当前Trigger使用的cron
                        String currentCron = currTrigger.getCronExpression();
                        // 如果不一致,则刷新任务
                        if (!currentCron.equals(jobCron)) {
                            //表达式调度构建器
                            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(jobCron);
                            //按新的cronExpression表达式重新构建trigger
                            currTrigger = (CronTrigger) scheduler.getTrigger(currTriggerKey);
                            currTrigger = currTrigger.getTriggerBuilder().withIdentity(currTriggerKey).withSchedule(scheduleBuilder).build();
                            // 按新的trigger重新设置job执行
                            scheduler.rescheduleJob(currTriggerKey, currTrigger); 
                        }
                    }
                }
            }
        } catch (Exception e) {
            System.out.println("checkExists失败" + e); 
        }
    }
}

ReadDbJob任务类

public class ReadDbJob extends QuartzJobBean {
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss");
        System.out.println(simpleDateFormat.format(new Date()) + ":ReadDbJob:"+jobExecutionContext.getJobDetail().getKey().toString());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值