產(chǎn)生這個(gè)需求的主要原因是寫了個(gè)簡(jiǎn)單的爬取網(wǎng)易新聞的方法,但是總不能一直自己手動(dòng)執(zhí)行吧,于是了解到了定時(shí)任務(wù)以及Quartz這個(gè)強(qiáng)大的框架,能夠設(shè)定執(zhí)行時(shí)間間隔和和何時(shí)停止等等。總之框架就是非常的優(yōu)秀。
本文主要介紹使用Spring Boot項(xiàng)目集成Quartz的過程及遇到的一些問題。
第一,依賴的兩個(gè)重要包。
<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
其中,spring-context-support的作用為,quartz在運(yùn)行任務(wù)時(shí),是在spring容器里面吧,會(huì)用到其中的一些bean也就是類的實(shí)例吧,這個(gè)包就對(duì)這個(gè)需求實(shí)現(xiàn)了支持。
第二,以我自身需求為例,我想要定時(shí)執(zhí)行的任務(wù)是crawlBasicNewsInfo()這個(gè)方法,具體方法內(nèi)容就不給出了。這個(gè)任務(wù)方法的類實(shí)現(xiàn)Job類,并覆寫execute方法,如下代碼所示:
public class CrawlNewsJob implements Job {
@Autowired
private NewsRepository newsRepository;
@Autowired
private NewsmoduleRepository newsmoduleRepository;
private static Logger logger = Logger.getLogger(CrawlNewsJob.class);
@Override
public void execute(JobExecutionContext context){
crawlBasicNewsInfo();
}
第三,實(shí)現(xiàn)對(duì)job實(shí)例注入spring容器里面的一些bean的任務(wù),首先是覆寫框架創(chuàng)建JobInstance的方式,,定制我們自己的SpringJobFactory。不這么做的話,肯定會(huì)空指針了。
@Component
public class SpringJobFactory extends AdaptableJobFactory{
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception{
//調(diào)用父類獲取jobinstance
Object jobinstance = super.createJobInstance(bundle);
//此處給job實(shí)例注入spring容器中的bean
capableBeanFactory.autowireBean(jobinstance);
return jobinstance;
}
}
接著通過@Configuration、@Bean等注解進(jìn)行配置,這里就是Spring Boot的方便之處了,不需要xml去配置了。值得注意的是,對(duì)于注入的Schduler,必須要加入@Primary確保注入的是我們這個(gè)Bean,而不是框架中的,不加會(huì)出現(xiàn)Field scheduler in RecommenderApplication required a single bean, but 2 were found報(bào)錯(cuò)。
@Configuration
public class QuartzConfig {
@Autowired
private SpringJobFactory springJobFactory;
@Bean(name = "SchedulerFactoryBean")
public SchedulerFactoryBean schedulerFactoryBean(){
SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
schedulerFactoryBean.setJobFactory(springJobFactory);
return schedulerFactoryBean;
}
@Bean(name = "Scheduler")
@Primary
public Scheduler scheduler(){
return schedulerFactoryBean().getScheduler();
}
}
第四,實(shí)現(xiàn)了上述功能就可以實(shí)現(xiàn)定時(shí)任務(wù)了,但是如果現(xiàn)在需要項(xiàng)目啟動(dòng)時(shí)就一直運(yùn)行怎么辦?項(xiàng)目啟動(dòng)時(shí),需要跟Spring Boot一起運(yùn)行的話,Spring Boot提供了兩種自啟動(dòng)方式,一個(gè)是CommandLineRunner,一個(gè)是ApplicationRunner兩個(gè)接口,實(shí)現(xiàn)它的run方法,把你的定時(shí)任務(wù)放在其中就好啦。比如我的下面代碼所示。
@SpringBootApplication
public class RecommenderApplication implements ApplicationRunner{
private static Logger logger = Logger.getLogger(CrawlNewsJob.class);
@Autowired
private Scheduler scheduler;
public static void main(String[] args) throws SchedulerException,FileLockInterruptionException {
SpringApplication.run(RecommenderApplication.class, args);
}
@Override
public void run(ApplicationArguments args) throws Exception{
try {
//Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
scheduler.start();
System.out.println("Quartz Start !");
//具體任務(wù)
JobDetail job = JobBuilder.newJob(CrawlNewsJob.class).withIdentity("job1","group1").build();
//觸發(fā)器
SimpleScheduleBuilder simpleScheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(60).repeatForever();
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1","group1").startNow().withSchedule(simpleScheduleBuilder).build();
scheduler.scheduleJob(job,trigger);
//睡眠
TimeUnit.MINUTES.sleep(360);
scheduler.shutdown();
System.out.println("scheduler shutdown ! ");
}catch(Exception e){e.printStackTrace();}
}
}
實(shí)現(xiàn)Spring Boot集成Quartz并使得項(xiàng)目啟動(dòng)時(shí)執(zhí)行某些定時(shí)任務(wù),大致就是上面這些內(nèi)容了。開始你的表演吧。
原文:http://netrookie.cn/Spring-Boot%E9%9B%86%E6%88%90Quartz%E5%AE%9E%E7%8E%B0%E5%AE%9A%E6%97%B6%E4%BB%BB%E5%8A%A1/
公眾號(hào):netrookie