Spring Boot整合之定時任務
阿新 • • 發佈:2018-11-12
@Scheduled適用與監聽任務較少的,而Quartz適合較多的,為確保可伸縮性,Quartz採用了基於多執行緒的架構。啟動時,框架初始化一套worker執行緒,這套執行緒被排程器用來執行預定的作業。這就是Quartz怎樣能併發執行多個作業的原理。Quartz依賴一套鬆耦合的執行緒池管理部件來管理執行緒環境。
定時器:
1.Scheduled:spring 3.0 後自帶的定時器
2.Quartz:第三放定時器框架
1.Scheduled
1.1 建立任務類
package com.wyp.util; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.util.Date; /** * Scheduled定時器 */ @Component public class Schedule { @Scheduled(fixedRate = 2000) public void task() { System.out.println("啟動定時任務:" + new Date()); } }
使用@Scheduled 定義任務執行時間,程式碼中表示每隔2秒執行一次任務
1.2啟動定時任務
在啟動類上新增@EnableScheduling,如下:
package com.wyp; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.scheduling.annotation.EnableScheduling; @EnableScheduling @SpringBootApplication public class SpringbootApplication { public static void main(String[] args) { SpringApplication.run(SpringbootApplication.class, args); } }
啟動,到控制檯看結果。
2.Quartz
2.1匯入依賴
<!--匯入Quartz依賴--> <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> <!--匯入Quartz依賴-->
2.2 建立定時任務類
package com.wyp.util;
import com.wyp.dao.TTestDao;
import com.wyp.pojo.TTest;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
public class MyJob implements Job {
@Autowired
private TTestDao tTestDao;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("========quartz 測試=========="+new Date());
}
}
2.3 建立配置類
package com.wyp.util;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
/**
* Quartz定時配置類
*/
@Configuration
public class QuartzConfiguration {
/**
* Job 工廠
* @return
*/
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(MyJob.class);
return factory;
}
/**
* Trigger 工廠
* @param jobDetailFactory
* @return
*/
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactory){
SimpleTriggerFactoryBean factory = new SimpleTriggerFactoryBean();
//執行間隔時間
factory.setRepeatInterval(5000);
//重複執行次數
factory.setRepeatCount(3);
return factory;
}
/**
* Trigger 工廠
* @param jobDetailFactory
* @return
*/
@Bean
public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactory){
CronTriggerFactoryBean factory = new CronTriggerFactoryBean();
factory.setJobDetail(jobDetailFactory.getObject());
factory.setCronExpression("0/5 * * * * ?");
return factory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactory){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setTriggers(cronTriggerFactory.getObject());
return factory;
}
}
在啟動類上新增@EnableScheduling
2.4 依賴注入問題
package com.wyp.util;
import com.wyp.dao.TTestDao;
import com.wyp.pojo.TTest;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Date;
public class MyJob implements Job {
@Autowired
private TTestDao tTestDao;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// System.out.println("========quartz 測試=========="+new Date());
TTest tTestListById = tTestDao.getTTestListById(2);
System.out.println(tTestListById);
}
}
但是MyJob 生命週期並沒有被 Spring 容器管理,因此無法注入 UserService,當定時器執行任務時會報空指標異常。
解決辦法:
自定義任務工廠,重寫建立任務例項的方法:
package com.wyp.util;
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("CustomAdaptableJobFactory")
public class CustomAdaptableJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory autowireCapableBeanFactory;
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception{
Object object = super.createJobInstance(bundle);
//將任務例項納入 Spring 容器中
this.autowireCapableBeanFactory.autowireBean(object);
return object;
}
}
修改QuartzConfiguration類:
原:
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactory){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setTriggers(cronTriggerFactory.getObject());
return factory;
}
現:
@Bean
public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactory,CustomAdaptableJobFactory customAdaptableJobFactory){
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setTriggers(cronTriggerFactory.getObject());
factory.setJobFactory(customAdaptableJobFactory);
return factory;
}
2.5 啟動定時任務
結果如下