美文网首页
Spring Boot集成Quartz实现定时任务

Spring Boot集成Quartz实现定时任务

作者: 江小林 | 来源:发表于2018-03-21 15:33 被阅读182次

    产生这个需求的主要原因是写了个简单的爬取网易新闻的方法,但是总不能一直自己手动执行吧,于是了解到了定时任务以及Quartz这个强大的框架,能够设定执行时间间隔和和何时停止等等。总之框架就是非常的优秀。

    本文主要介绍使用Spring Boot项目集成Quartz的过程及遇到的一些问题。

    第一,依赖的两个重要包。

    <!-- 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在运行任务时,是在spring容器里面吧,会用到其中的一些bean也就是类的实例吧,这个包就对这个需求实现了支持。

    第二,以我自身需求为例,我想要定时执行的任务是crawlBasicNewsInfo()这个方法,具体方法内容就不给出了。这个任务方法的类实现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();
        }
    

    第三,实现对job实例注入spring容器里面的一些bean的任务,首先是覆写框架创建JobInstance的方式,,定制我们自己的SpringJobFactory。不这么做的话,肯定会空指针了。

    @Component
    public class SpringJobFactory extends AdaptableJobFactory{
        @Autowired
        private AutowireCapableBeanFactory capableBeanFactory;
    
        @Override
        protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception{
            //调用父类获取jobinstance
            Object jobinstance = super.createJobInstance(bundle);
            //此处给job实例注入spring容器中的bean
            capableBeanFactory.autowireBean(jobinstance);
            return jobinstance;
        }
    }
    

    接着通过@Configuration、@Bean等注解进行配置,这里就是Spring Boot的方便之处了,不需要xml去配置了。值得注意的是,对于注入的Schduler,必须要加入@Primary确保注入的是我们这个Bean,而不是框架中的,不加会出现Field scheduler in RecommenderApplication required a single bean, but 2 were found报错。

    @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();
        }
    }
    

    第四,实现了上述功能就可以实现定时任务了,但是如果现在需要项目启动时就一直运行怎么办?项目启动时,需要跟Spring Boot一起运行的话,Spring Boot提供了两种自启动方式,一个是CommandLineRunner,一个是ApplicationRunner两个接口,实现它的run方法,把你的定时任务放在其中就好啦。比如我的下面代码所示。

    @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 !");
                //具体任务
                JobDetail job = JobBuilder.newJob(CrawlNewsJob.class).withIdentity("job1","group1").build();
    
                //触发器
                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();}
        }
    }
    

    实现Spring Boot集成Quartz并使得项目启动时执行某些定时任务,大致就是上面这些内容了。开始你的表演吧。

    原文: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/
    公众号:netrookie

    相关文章

      网友评论

          本文标题:Spring Boot集成Quartz实现定时任务

          本文链接:https://www.haomeiwen.com/subject/ugugqftx.html