1、普通的定時任務我們用Sping 自帶的scheduler就可以完成,但是需要從數據庫動態配置可能要用到Quartz了。
2、遇到的問題:單獨只定時一個任務,可以直接寫一個類,設置 jobDetail和cronTrigger,放到SchedulerFactoryBean中方可 。具體示例:
package pft.web.timing;
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 {
@Bean(name = "jobDetail")
public MethodInvokingJobDetailFactoryBean detailFactoryBean(ScheduledJob task) {//ScheduledJob 為定時任務的類
// ScheduleTask為需要執行的任務
MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean();
/*
* 是否並發執行
* 例如每5s執行一次任務,但是當前任務還沒有執行完,就已經過了5s了,
* 如果此處為true,則下一個任務會bing執行,如果此處為false,則下一個任務會等待上一個任務執行完后,再開始執行
*/
jobDetail.setConcurrent(true);
jobDetail.setName("scheduler");// 設置任務的名字
jobDetail.setGroup("scheduler_group");// 設置任務的分組,這些屬性都可以存儲在數據庫中,在多任務的時候使用
/*
* 這兩行代碼表示執行task對象中的scheduleTest方法。定時執行的邏輯都在scheduleTest。
*/
jobDetail.setTargetObject(task);
jobDetail.setTargetMethod("scheduleTest");//scheduleTest 定時任務中要執行的方法
return jobDetail;
}
@Bean(name = "jobTrigger")
public CronTriggerFactoryBean cronJobTrigger(MethodInvokingJobDetailFactoryBean jobDetail) {
CronTriggerFactoryBean tigger = new CronTriggerFactoryBean();
tigger.setJobDetail(jobDetail.getObject());
tigger.setCronExpression("0/6 * * * * ?");// 表示每隔6秒鍾執行一次
//tigger.set
tigger.setName("myTigger");// trigger的name
return tigger;
}
@Bean(name = "scheduler")
public SchedulerFactoryBean schedulerFactory(Trigger cronJobTrigger) {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
//設置是否任意一個已定義的Job會覆蓋現在的Job。默認為false,即已定義的Job不會覆蓋現有的Job。
bean.setOverwriteExistingJobs(true);
// 延時啟動,應用啟動5秒后 ,定時器才開始啟動
bean.setStartupDelay(5);
// 注冊定時觸發器
bean.setTriggers(cronJobTrigger);
return bean;
}
//多任務時的Scheduler,動態設置Trigger。一個SchedulerFactoryBean可能會有多個Trigger
@Bean(name = "multitaskScheduler")
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
return schedulerFactoryBean;
}
}
3、要有多個定時任務時:(參考地址:https://blog.csdn.net/mengruobaobao/article/details/79106343)
一、首先新建 MyJobFactory ,
目的是:
在具體的Job 中 需要Spring 注入一些Service。所以我們要自定義一個jobfactory, 讓其在具體job 類實例化時 使用Spring 的API 來進行依賴注入。
package pft.web.timing;
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 MyJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
// 調用父類的方法
Object jobInstance = super.createJobInstance(bundle);
// 進行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
二、配置 SchedulerFactoryBean
package pft.web.timing;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class SchedulerListener {
@Autowired
private MyJobFactory myJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(myJobFactory);//將job實例化,能夠操作進行Spring 注入
return schedulerFactoryBean;
}
}
3、分別給定時任務設置 jobDetail和cronTrigger ,注冊定時觸發器 SchedulerFactoryBean
package pft.web.timing;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Service;
@Service
public class MyScheduler {
@Autowired
SchedulerFactoryBean schedulerFactoryBean;
public void scheduleJobs() throws SchedulerException {
Scheduler scheduler = schedulerFactoryBean.getScheduler();
startJob1(scheduler);
startJob2(scheduler);
}
private void startJob1(Scheduler scheduler) throws SchedulerException{
JobDetail jobDetail = JobBuilder.newJob(ScheduledJob.class)
.withIdentity("job1", "group1").build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/3 * * * * ?");
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,cronTrigger);
}
private void startJob2(Scheduler scheduler) throws SchedulerException{
JobDetail jobDetail = JobBuilder.newJob(ScheduledJob2.class)
.withIdentity("job2", "group1").build();
CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule("0/6 * * * * ?");
CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity("trigger2", "group1")
.withSchedule(scheduleBuilder).build();
scheduler.scheduleJob(jobDetail,cronTrigger);
}
}
四、控制層調用 scheduleJobs 方法,開啟定時器
親測、能夠在job中的注入spring