springboot动态定时任务
SpringBoot设置动态定时任务
一、说明
1.在我们日常的开发中,很多时候,定时任务都不是写死的,而是写到数据库中,从而实现定时任务的动态配置。
2.定时任务执行时间可根据数据库中某个设置字段动态改变。
二、maven依赖
<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> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency>
三、代码
1.输出测试类
import org.quartz.JobExecutionException;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@Component
@Configuration
@EnableScheduling
public class ScheduledJob {
public void execute() throws JobExecutionException {
System.out.println("hahaha");
}
}
2.Quartz配置类
import org.quartz.Trigger; 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 QuartzConfigration { /** * attention: * Details:配置定时任务 */ @Bean(name = "jobDetail") public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledJob task) {// ScheduleTask为需要执行的任务 MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); /* * 是否并发执行 * 例如每5s执行一次任务,但是当前任务还没有执行完,就已经过了5s了, * 如果此处为true,则下一个任务会执行,如果此处为false,则下一个任务会等待上一个任务执行完后,再开始执行 */ jobDetail.setConcurrent(false); jobDetail.setName("srd-chhliu");// 设置任务的名字 jobDetail.setGroup("srd");// 设置任务的分组,这些属性都可以存储在数据库中,在多任务的时候使用 /* * 为需要执行的实体类对应的对象 */ jobDetail.setTargetObject(task); /* * sayHello为需要执行的方法 * 通过这几个配置,告诉JobDetailFactoryBean我们需要执行定时执行ScheduleTask类中的sayHello方法 */ jobDetail.setTargetMethod("execute"); return jobDetail; } /** * attention: * Details:配置定时任务的触发器,也就是什么时候触发执行定时任务 */ @Bean(name = "jobTrigger") public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) { CronTriggerFactoryBean tigger = new CronTriggerFactoryBean(); tigger.setJobDetail(jobDetail.getObject()); tigger.setCronExpression("0 10 15 * * ?");// 初始时的cron表达式 tigger.setName("srd-chhliu");// trigger的name return tigger; } /** * attention: * Details:定义quartz调度工厂 */ @Bean(name = "schedulerTwo") public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) { SchedulerFactoryBean bean = new SchedulerFactoryBean(); // 用于quartz集群,QuartzScheduler 启动时更新己存在的Job bean.setOverwriteExistingJobs(true); // 延时启动,应用启动1秒后 bean.setStartupDelay(1); // 注册触发器 bean.setTriggers(cronJobTrigger); return bean; } }
3.定时请求数据库获取时间类 注意sql语句的更改及判断 查询频率可自行更改
package com.jdkeji.shares.quartz; import javax.annotation.Resource; import org.mybatis.spring.SqlSessionTemplate; import org.quartz.CronScheduleBuilder; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import com.jdkeji.shares.config.model.BusinessConfig; @Configuration @EnableScheduling @Component public class ScheduleRefreshDatabase { @Autowired private SqlSessionTemplate st; @Resource(name = "jobDetail") private JobDetail jobDetail; @Resource(name = "jobTrigger") private CronTrigger cronTrigger; @Resource(name = "schedulerTwo") private Scheduler scheduler; @Scheduled(fixedRate = 5000) // 每隔5s查库,并根据查询结果决定是否重新设置定时任务 public void scheduleUpdateCronTrigger() throws SchedulerException { CronTrigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); String currentCron = trigger.getCronExpression();// 当前Trigger使用的 BusinessConfig bc = st.selectOne("BusinessConfig.selectByExample"); System.out.println(currentCron); String [] date = bc.getClxg().split(":"); String cron = "0 " + date[1] + " " + date[0] + " * * ?"; System.out.println(cron); if (currentCron.equals(cron)) { // 如果当前使用的cron表达式和从数据库中查询出来的cron表达式一致,则不刷新任务 } else { // 表达式调度构建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron); // 按新的cronExpression表达式重新构建trigger trigger = (CronTrigger) scheduler.getTrigger(cronTrigger.getKey()); trigger = trigger.getTriggerBuilder().withIdentity(cronTrigger.getKey()) .withSchedule(scheduleBuilder).build(); // 按新的trigger重新设置job执行 scheduler.rescheduleJob(cronTrigger.getKey(), trigger); currentCron = cron; } } }
四、注意
QuartzConfigration类中的detailFactoryBean(ScheduledJob)
ScheduledJob就是我们的输出测试类