• Spring Boot 入门(九):集成Quartz定时任务


    本片文章续《Spring Boot 入门(八):集成RabbitMQ消息队列》,关于Quartz定时任务请参考《Quartz的基本使用之入门(2.3.0版本)

    spring boot实现定时任务,除了集成Quartz外,还可以直接使用scheduler注解。使用1个简单的注解就可以完成,为什么还要较为复杂的集成Quartz呢?这里我简单回答下这2中方式的区别,这也是我在项目中为什么要选择Quartz这种方式。

    1.scheduler注解方式,一旦定时任务产生异常,那么此定时任务就无法再次启动,意味该定时任务就失效了,而Quartz不会。

    2.scheduler注解方式,当前面的定时任务没有完成的时候,无法再次开启定时任务,这说明scheduler注解方式是单线程,而Quartz是多线程,同一定时任务可以并发处理。

    3.scheduler注解方式,对于定时的格式很少,只能简单的在注解中配置,很多复杂的定时任务没法完成,而Quartz的格式很丰富,可以配置各种各样的定时任务。

    基于上述原因,定时任务应该选择Quartz。

    1.增加依赖

     1 <!--quartz-->
     2         <dependency>
     3             <groupId>org.quartz-scheduler</groupId>
     4             <artifactId>quartz</artifactId>
     5             <version>2.2.1</version>
     6         </dependency>
     7         <!-- 该依赖必加,里面有sping对schedule的支持 -->
     8         <dependency>
     9             <groupId>org.springframework</groupId>
    10             <artifactId>spring-context-support</artifactId>
    11         </dependency>

    2.增加conf

     1 package 2 
     3 import org.quartz.*;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Service;
     6 
     7 
     8 /**
     9  * @program: 
    10  * @description: 定时任务创建job,通过注入Scheduler对任务进行操作
    11  * @author: DZ
    12  * @create: 2019-10-19 18:28
    13  **/
    14 @Service
    15 public class QuartzConf {
    16     private static final String JOB_GROUP = "job_group";
    17     private static final String TRIGGER_GROUP = "trigger_group";
    18     @Autowired
    19     private Scheduler scheduler;
    20 
    21     /**
    22      * 创建定时任务
    23      *定义相应的任务(JobDetial)和触发器(trigger),并将其加到一个执行日程(Scheduler)中,并通过监听器启动日程。
    24      * @param jobDetailName
    25      * @param cronExpression
    26      * @param jobClass
    27      * @throws SchedulerException
    28      */
    29     public void createScheduleJob(String jobDetailName, String cronExpression, Class<? extends Job> jobClass) throws SchedulerException {
    30         JobDetail jobDetail = JobBuilder.newJob(jobClass)
    31                 .withIdentity("task_" + jobDetailName, JOB_GROUP).storeDurably().requestRecovery().build();
    32         CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
    33         Trigger trigger = TriggerBuilder.newTrigger().withIdentity("task_" + jobDetailName, TRIGGER_GROUP).withSchedule(scheduleBuilder).build();
    34         scheduler.scheduleJob(jobDetail, trigger);
    35     }
    36 }

    3.增加过滤器

     6 import lombok.extern.slf4j.Slf4j;
     7 import org.quartz.SchedulerException;
     8 import org.slf4j.MDC;
     9 import org.springframework.beans.factory.annotation.Autowired;
    10 import org.springframework.context.ApplicationListener;
    11 import org.springframework.context.annotation.Configuration;
    12 import org.springframework.context.event.ContextRefreshedEvent;
    13 
    14 import java.util.UUID;
    15 
    16 /**
    17  * @program: 
    18  * @description: 启动监听去初始化Quartz
    19  * @author: DZ
    20  * @create: 2019-10-19 18:32
    21  **/
    22 @Slf4j
    23 @Configuration
    24 public class ApplicationStartQuartzJobListener implements ApplicationListener<ContextRefreshedEvent> {
    25     @Autowired
    26     private QuartzConf quartzConf;
    27 
    28    /* 时间格式:
    29     *    *     *     *    *     *   *
    30     [秒] [分] [小时] [日] [月] [周] [年]*/
    31 
    32     /**
    33      * 初始启动quartz
    34      */
    35     @Override
    36     public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
    37         try {
    38             log.info("任务开始启动...");
    39           40             quartzConf.createScheduleJob("TestTask", "*/30 * * * * ?", TestTask.class);
    41             log.info("任务已经启动...");
    42         } catch (SchedulerException e) {
    43             log.error("定时任务启动失败", e);
    44         }
    45     }
    46 }

    如果整个项目就一个定时任务,其实也不需要过滤器,直接将定时任务的类名写在cong中即可。如果有多个定时任务,定义多个trigger和job也可以。这样代码的冗余度比较高

    此监听器的作用在于:项目启动的时候,监听器将所有的定时任务注册到日程中,相当于开启定时任务。从而做到了只需要定义一套trigger和job就可以写多个定时任务。

    4.写定时任务

     1  2 
     3  4 import lombok.extern.slf4j.Slf4j;
     5 import org.quartz.Job;
     6 import org.quartz.JobExecutionContext;
     7 import org.quartz.JobExecutionException;
     8 import org.quartz.JobKey;
     9 import org.slf4j.MDC;
    10 
    11 import java.util.UUID;
    12 
    13 /**
    14  * @program:
    15  * @description: 测试定时任务
    16  * @author: DZ
    17  * @create: 2019-10-19 18:49
    18  **/
    19 @Slf4j
    20 public class TestTask implements Job {
    21     @Override
    22     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    23        25         JobKey key = jobExecutionContext.getJobDetail().getKey();
    26         // todo 业务逻辑
    27         log.info("----------" + key + "任务执行中,currentTime:" + DateUtil.getCurrentDate());
    28     }
    29 }

     这个位置除了实现Job接口外,还可以继承QuartzJobBean类,其实QuartzJobBean也是Job的子类,只不过对部分参数进行了初始化

    启动服务,查看结果

    此外,如果不对定时任务做线程池的配置,那么默认是10个线程,这里也可以增加对线程池的配置,在yml中增加属性:

     1 Spring:  
     2 #  quartz定时器配置
     3   quartz:
     4     properties:
     5       org:
     6         quartz:
     7           scheduler:
     8             instanceName: quartzScheduler
     9             instanceId: AUTO
    10           threadPool:
    11             class: org.quartz.simpl.SimpleThreadPool
    12             threadCount: 20
    13             threadPriority: 5
    14             threadsInheritContextClassLoaderOfInitializingThread: true

    此时就是定义了20个线程

  • 相关阅读:
    ora12514
    telnet到虚拟机上的red hat linux失败——解决办法
    linux下监听的配置
    本机win7系统与虚拟机中的linux系统实现通讯
    ORA01078: failure in processing system parameters LRM00109: could not open parameter file '/oradata/oracle/112/dbs/in
    Xmanager无法登录Red Hat Linux——解决方法
    几种常见算法的介绍及复杂度分析(转)
    Linux学习笔记18cal显示日历
    Linux学习笔记14架设Apache http服务器
    Installing Oracle Database 10g on Linux
  • 原文地址:https://www.cnblogs.com/dz-boss/p/11729505.html
Copyright © 2020-2023  润新知