Springboot Quartz 整合實現方案
阿新 • • 發佈:2019-01-26
1.首先自定義一個Scheduler,任務排程器。記得@EnableScheduling
需要新增到啟動類
2.採用spring自帶@Scheduled
,定時去資料庫掃碼獲取到任務,將任務新增到Quartz
3.將需要操作的任務一一實現Job介面,資料插入到資料庫中。
程式碼如下
package com.mjitech.quartz; import org.quartz.Scheduler; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import java.io.IOException; import java.util.Properties; @Configuration public class QuartzConfigration { @Autowired private MaxboxQuartzJobFactory jobFactory; //獲取工廠bean @Bean public SchedulerFactoryBean schedulerFactoryBean() { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); try { schedulerFactoryBean.setQuartzProperties(quartzProperties()); schedulerFactoryBean.setJobFactory(jobFactory); } catch (IOException e) { e.printStackTrace(); } return schedulerFactoryBean; } //指定quartz.properties @Bean public Properties quartzProperties() throws IOException { PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean(); propertiesFactoryBean.setLocation(new ClassPathResource("/conf/quartz.properties")); propertiesFactoryBean.afterPropertiesSet(); return propertiesFactoryBean.getObject(); } //建立schedule @Bean(name = "scheduler") public Scheduler scheduler() { return schedulerFactoryBean().getScheduler(); } }
package com.mjitech.quartz; import lombok.Data; import javax.persistence.*; @Entity @Table(name = "c_schedule_triggers") @Data public class CScheduleTrigger { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String cron; //時間表達式 private Boolean status; //使用狀態 false:禁用 true:啟用 private String jobName; //任務名稱 private String jobGroup; //任務分組 }
package com.mjitech.quartz; import com.mjitech.jpa.CScheduleTriggerRepository; import org.quartz.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import java.util.List; @Component public class ScheduleTriggerService { private static final Logger logger = LoggerFactory.getLogger(ScheduleTriggerService.class); @Autowired private Scheduler scheduler; @Autowired private CScheduleTriggerRepository triggerRepository; /** *每分鐘執行一次 * 將任務放進到資料庫,自動讀取放入佇列 */ @Scheduled(cron = "0 18 11 * * ?") public void refreshTrigger() { try { //查詢出資料庫中所有的定時任務 List<CScheduleTrigger> jobList = triggerRepository.findAll(); if (!CollectionUtils.isEmpty(jobList)) { for (CScheduleTrigger scheduleJob : jobList) { Boolean status = scheduleJob.getStatus(); //該任務觸發器目前的狀態 TriggerKey triggerKey = TriggerKey.triggerKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey); //說明本條任務還沒有新增到quartz中 if (null == trigger) { if (!status) { //如果是禁用,則不用建立觸發器 continue; } JobDetail jobDetail = null; try { //建立JobDetail(資料庫中job_name存的任務全路徑,這裡就可以動態的把任務注入到JobDetail中) jobDetail = JobBuilder.newJob((Class<? extends Job>) Class.forName(scheduleJob.getJobName())).withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).build(); //表示式排程構建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(scheduleJob.getCron()); ///設定定時任務的時間觸發規則 trigger = TriggerBuilder.newTrigger().withIdentity(scheduleJob.getJobName(), scheduleJob.getJobGroup()).withSchedule(scheduleBuilder).build(); //把trigger和jobDetail注入到排程器 scheduler.scheduleJob(jobDetail, trigger); } catch (ClassNotFoundException e) { e.printStackTrace(); } } else { //說明查出來的這條任務,已經設定到quartz中了 // Trigger已存在,先判斷是否需要刪除,如果不需要,再判定是否時間有變化 if (status.equals("0")) { //如果是禁用,從quartz中刪除這條任務 JobKey jobKey = JobKey.jobKey(scheduleJob.getJobName(), scheduleJob.getJobGroup()); scheduler.deleteJob(jobKey); continue; } String searchCron = scheduleJob.getCron(); //獲取資料庫的 String currentCron = trigger.getCronExpression(); if (!searchCron.equals(currentCron)) { //說明該任務有變化,需要更新quartz中的對應的記錄 //表示式排程構建器 CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(searchCron); //按新的cronExpression表示式重新構建trigger trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build(); //按新的trigger重新設定job執行 scheduler.rescheduleJob(triggerKey, trigger); } } } } } catch (Exception e) { logger.error("定時任務每日重新整理觸發器任務異常,異常資訊:", e); } } }
package com.mjitech.quartz;
import com.mjitech.jpa.CScheduleTriggerRepository;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
@DisallowConcurrentExecution
public class MyTask implements Job {
@Autowired
private CScheduleTriggerRepository jobRepository;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
//可以通過context拿到執行當前任務的quartz中的很多資訊,如當前是哪個trigger在執行該任務
CronTrigger trigger = (CronTrigger) jobExecutionContext.getTrigger();
String corn = trigger.getCronExpression();
String jobName = trigger.getKey().getName();
String jobGroup = trigger.getKey().getGroup();
System.out.println("開始了");
} catch (Exception e) {
}
}
}
package com.mjitech.quartz;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
public class MaxboxQuartzJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}