Spring Boot集成Quartz實(shí)現(xiàn)定時(shí)任務(wù)

產(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容