Springboot 集成Quartz的使用(解決quartz的job無法注入spring對象的問題)


                                                          

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

 

 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM