相關文章
前言
最近在項目中使用到定時任務,之前一直都是使用Quartz 來實現,最近看Spring 基礎發現其實Spring 提供 Spring Schedule 可以幫助我們實現簡單的定時任務功能。
下面說一下兩種方式在Spring Boot 項目中的使用。
Spring Schedule 實現定時任務
Spring Schedule 實現定時任務有兩種方式 1. 使用XML配置定時任務, 2. 使用 @Scheduled 注解。 因為是Spring Boot 項目 可能盡量避免使用XML配置的形式,主要說注解的形式.
Spring Schedule 提供三種形式的定時任務:
固定等待時間 @Scheduled(fixedDelay = 時間間隔 )
@Component
public class ScheduleJobs {
public final static long SECOND = 1 * 1000;
FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
@Scheduled(fixedDelay = SECOND * 2)
public void fixedDelayJob() throws InterruptedException {
TimeUnit.SECONDS.sleep(2);
System.out.println("[FixedDelayJob Execute]"+fdf.format(new Date()));
}
}
固定間隔時間 @Scheduled(fixedRate = 時間間隔 )
@Component
public class ScheduleJobs {
public final static long SECOND = 1 * 1000;
FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
@Scheduled(fixedRate = SECOND * 4)
public void fixedRateJob() {
System.out.println("[FixedRateJob Execute]"+fdf.format(new Date()));
}
}
Corn表達式 @Scheduled(cron = Corn表達式)
@Component
public class ScheduleJobs {
public final static long SECOND = 1 * 1000;
FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
@Scheduled(cron = "0/4 * * * * ?")
public void cronJob() {
System.out.println("[CronJob Execute]"+fdf.format(new Date()));
}
}
Spring Boot 整合 Quartz 實現定時任務
添加Maven依賴
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
Spring Boot 整合 Quartz
Spring 項目整合 Quartz 主要依靠添加 SchedulerFactoryBean 這個 FactoryBean ,所以在maven 依賴中添加 spring-context-support 。
首先添加 QuartzConfig 類 來聲明相關Bean
@Configuration
public class QuartzConfig {
@Autowired
private SpringJobFactory springJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(springJobFactory);
return schedulerFactoryBean;
}
@Bean
public Scheduler scheduler() {
return schedulerFactoryBean().getScheduler();
}
}
這里我們需要注意 我注入了一個 自定義的JobFactory ,然后 把其設置為SchedulerFactoryBean 的 JobFactory。其目的是因為我在具體的Job 中 需要Spring 注入一些Service。
所以我們要自定義一個jobfactory, 讓其在具體job 類實例化時 使用Spring 的API 來進行依賴注入。
SpringJobFactory 具體實現:
@Component
public class SpringJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
具體使用 (摘取自項目代碼):
@Service
public class QuartzEventServiceImpl implements QuartzEventService {
private static final String JOB_GROUP = "event_job_group";
private static final String TRIGGER_GROUP = "event_trigger_group";
@Autowired
private Scheduler scheduler;
@Override
public void addQuartz(Event event) throws SchedulerException {
JSONObject eventData = JSONObject.parseObject(event.getEventData());
Date triggerDate = eventData.getDate("date");
JobDetail job = JobBuilder.newJob(EventJob.class).withIdentity(event.getId().toString(), JOB_GROUP).usingJobData(buildJobDateMap(event)).build();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity(event.getId().toString(), TRIGGER_GROUP).startAt(triggerDate).build();
scheduler.scheduleJob(job, trigger);
}