SpringBoot設置動態定時任務java
1、說明spring
1.在咱們平常的開發中,不少時候,定時任務都不是寫死的,而是寫到數據庫中,從而實現定時任務的動態配置。sql
2.定時任務執行時間可根據數據庫中某個設置字段動態改變。數據庫
2、maven依賴mybatis
<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>
3、代碼併發
1.輸出測試類maven
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配置類ide
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; } } }
4、注意ui
QuartzConfigration類中的detailFactoryBean(ScheduledJob)
ScheduledJob就是咱們的輸出測試類