zoukankan      html  css  js  c++  java
  • Spring Boot整合Scheduled定时任务器、整合Quartz定时任务框架

    首先说明一下,这里使用的是Springboot2.2.6.RELEASE版本,由于Springboot迭代很快,所以要注意版本问题。

    1、Scheduled定时任务器:是Spring3.0以后自带的一个定时任务器。

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     4     <modelVersion>4.0.0</modelVersion>
     5     <parent>
     6         <groupId>org.springframework.boot</groupId>
     7         <artifactId>spring-boot-starter-parent</artifactId>
     8         <version>2.2.6.RELEASE</version>
     9         <relativePath/> <!-- lookup parent from repository -->
    10     </parent>
    11     <groupId>com.bie.springboot</groupId>
    12     <artifactId>springboot-job</artifactId>
    13     <version>0.0.1-SNAPSHOT</version>
    14     <name>springboot-job</name>
    15     <description>Demo project for Spring Boot</description>
    16 
    17     <properties>
    18         <java.version>1.8</java.version>
    19     </properties>
    20 
    21     <dependencies>
    22         <!-- springBoot 的启动器 -->
    23         <dependency>
    24             <groupId>org.springframework.boot</groupId>
    25             <artifactId>spring-boot-starter-web</artifactId>
    26         </dependency>
    27         <!-- lombok的依赖包 -->
    28         <dependency>
    29             <groupId>org.projectlombok</groupId>
    30             <artifactId>lombok</artifactId>
    31             <optional>true</optional>
    32         </dependency>
    33         <!-- springBoot测试的启动器 -->
    34         <dependency>
    35             <groupId>org.springframework.boot</groupId>
    36             <artifactId>spring-boot-starter-test</artifactId>
    37             <scope>test</scope>
    38             <!--<exclusions>
    39                 <exclusion>
    40                     <groupId>org.junit.vintage</groupId>
    41                     <artifactId>junit-vintage-engine</artifactId>
    42                 </exclusion>
    43             </exclusions>-->
    44         </dependency>
    45         <!-- 添加 Scheduled坐标 -->
    46         <dependency>
    47             <groupId>org.springframework</groupId>
    48             <artifactId>spring-context-support</artifactId>
    49         </dependency>
    50 
    51     </dependencies>
    52 
    53     <build>
    54         <plugins>
    55             <plugin>
    56                 <groupId>org.springframework.boot</groupId>
    57                 <artifactId>spring-boot-maven-plugin</artifactId>
    58             </plugin>
    59         </plugins>
    60     </build>
    61 
    62 </project>

    编写定时任务类,代码如下所示:

     1 package com.bie.springboot.utils;
     2 
     3 import org.springframework.scheduling.annotation.Scheduled;
     4 import org.springframework.stereotype.Component;
     5 
     6 import java.text.SimpleDateFormat;
     7 import java.util.Date;
     8 
     9 /**
    10  * @ProjectName: springboot-job
    11  * @Package: com.bie.springboot.utils
    12  * @ClassName: ScheduledDemo
    13  * @Author: biehl
    14  * @Description: ${description}
    15  * @Date: 2020/5/21 15:05
    16  * @Version: 1.0
    17  * <p>
    18  * Scheduled 定时任务
    19  */
    20 @Component
    21 public class ScheduledDemo {
    22 
    23     /**
    24      * 定时任务方法。
    25      *
    26      * @Scheduled:设置定时任务。
    27      *
    28      * cron 属性:cron表达式,定时任务触发是时间的一个字符串表达形式。
    29      */
    30     @Scheduled(cron = "0/2 * * * * ?") //每2秒钟触发一次方法。
    31     public void scheduledMethod() {
    32         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    33         System.out.println("定时器被触发: " + sdf.format(new Date()));
    34     }
    35 
    36 }

    在启动类中开启定时任务的使用,默认不开启:

     1 package com.bie.springboot;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.scheduling.annotation.EnableScheduling;
     6 
     7 @SpringBootApplication
     8 @EnableScheduling // 在启动类中开启定时任务的使用,默认不开启
     9 public class SpringbootJobApplication {
    10 
    11     public static void main(String[] args) {
    12         SpringApplication.run(SpringbootJobApplication.class, args);
    13     }
    14 
    15 }

    运行效果,如下所示:

    2、cron表达式讲解,Cron 表达式是一个字符串,分为6或7个域,每一个域代表一个含义,Cron有如下两种语法格式:

    2.1)、第一种:Seconds Minutes Hours Day Month Week Year。秒、分钟、小时、天、月、周、年。

    2.2)、第二种:Seconds Minutes Hours Day Month Week。秒、分钟、小时、天、月、周,推荐此种写法。

    2.3)、corn从左到右(用空格隔开):秒、分、小时、月份中的日期、月份、星期中的日期、年份。

    2.4)、各字段的含义。

    位置 时间域名 允许值 允许的特殊字符
    1 0-59 , - * /
    2 分钟 0-59 , - *  /
    3 小时 0-23 , - *  /
    4 1-31 , - *  / L W C
    5 1-12 , - *  /
    6 星期 1-7 , - *  / ? L C #
    7 年(可选) 1970-2099 , - *  /

    2.5、Cron 表达式的时间字段除允许设置数值外,还可使用一些特殊的字符,提供列表、范围、通配符等功 能,细说如下:

      1)、星号(*) :可用在所有字段中,表示对应时间域的每一个时刻,例如,*在分钟字段时,表示"每分钟"。

      2)、问号(?):该字符只在日期和星期字段中使用,它通常指定为"无意义的值",相当于占位符。

      3)、减号(-) :表达一个范围,如在小时字段中使用"10-12",则表示从 10 到 12 点,即 10,11,12。

      4)、逗号(,) :表达一个列表值,如在星期字段中使用"MON,WED,FRI",则表示星期一,星期三和星期五。

      5)、斜杠(/) :x/y 表达一个等步长序列,x 为起始值,y 为增量步长值。如在分钟字段中使用 0/15,则 表示为 0,15,30 和 45 秒,而 5/15 在分钟字段中表示 5,20,35,50,你也可以使用*/y,它等同于 0/y。

    注意:斜杠/和不使用斜杠的写法,比如第一位,如果不写斜杠/,那么表示每分钟的第几秒执行,如果写斜杠/表示每隔几秒执行。

      6)、L :该字符只在日期和星期字段中使用,代表"Last"的意思,但它在两个字段中意思不同。L 在日期 字段中,表示这个月份的最后一天,如一月的 31 号,非闰年二月的 28 号;如果 L 用在星期中,则表示星 期六,等同于 7。但是,如果 L 出现在星期字段里,而且在前面有一个数值 X,则表示"这个月的最后 X 天", 例如,6L 表示该月的最后星期五;

      7)、W :该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如 15W 表示离该月 15 号最近的工作日,如果该月 15 号是星期六,则匹配 14 号星期五;如果 15 日是星期日, 则匹配 16 号星期一;如果 15 号是星期二,那结果就是 15 号星期二。但必须注意关联的匹配日期不能够 跨月,如你指定 1W,如果 1 号是星期六,结果匹配的是 3 号星期一,而非上个月最后的那天。W 字符串 只能指定单一日期,而不能指定日期范围。

      8)、LW 组合 :在日期字段可以组合使用 LW,它的意思是当月的最后一个工作日。
    井号(#):该字符只能在星期字段中使用,表示当月某个工作日。如 6#3 表示当月的第三个星期五(6 表示星期五,#3 表示当前的第三个),而 4#5 表示当月的第五个星期三,假设当月没有第五个星期三, 忽略不触发。

      9)、C :该字符只在日期和星期字段中使用,代表"Calendar"的意思。它的意思是计划所关联的日期, 如果日期没有被关联,则相当于日历中所有日期。例如 5C 在日期字段中就相当于日历 5 日以后的第一天。 1C 在星期字段中相当于星期日后的第一天。 Cron 表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

      10)、案例说明:Seconds Minutes Hours Day Month Week。秒、分钟、小时、天、月、周

        a、@Scheduled(cron = "0 0 1 1 1 ?")    //每年一月的一号的 1:00:00 执行一次。
        b、@Scheduled(cron = "0 0 1 1 1,6 ?")    //一月和六月的一号的 1:00:00 执行一次。
        c、@Scheduled(cron = "0 0 1 1 1,4,7,10 ?")    //每个季度的第一个月的一号的 1:00:00 执行一次。
        d、@Scheduled(cron = "0 0 1 1 * ?")    //每月一号 1:00:00 执行一次。
        e、@Scheduled(cron="0 0 1 * * *")    //每天凌晨 1 点执行一次。

    3、Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。

    3.1、Quartz 的使用思路:

      1)、job任务:你要做什么事?
      2)、Trigger触发器:你什么时候去做?
      3)、Scheduler任务调度:你什么时候需要去做什么事?

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
     4     <modelVersion>4.0.0</modelVersion>
     5     <parent>
     6         <groupId>org.springframework.boot</groupId>
     7         <artifactId>spring-boot-starter-parent</artifactId>
     8         <version>2.2.6.RELEASE</version>
     9         <relativePath/> <!-- lookup parent from repository -->
    10     </parent>
    11     <groupId>com.bie.springboot</groupId>
    12     <artifactId>springboot-quartz</artifactId>
    13     <version>0.0.1-SNAPSHOT</version>
    14     <name>springboot-quartz</name>
    15     <description>Demo project for Spring Boot</description>
    16 
    17     <properties>
    18         <java.version>1.8</java.version>
    19     </properties>
    20 
    21     <dependencies>
    22         <!-- springboot启动器 -->
    23         <dependency>
    24             <groupId>org.springframework.boot</groupId>
    25             <artifactId>spring-boot-starter-web</artifactId>
    26         </dependency>
    27         <!-- springboot测试启动器 -->
    28         <dependency>
    29             <groupId>org.springframework.boot</groupId>
    30             <artifactId>spring-boot-starter-test</artifactId>
    31             <scope>test</scope>
    32             <!--<exclusions>
    33                 <exclusion>
    34                     <groupId>org.junit.vintage</groupId>
    35                     <artifactId>junit-vintage-engine</artifactId>
    36                 </exclusion>
    37             </exclusions>-->
    38         </dependency>
    39         <!-- Quartz坐标 -->
    40         <dependency>
    41             <groupId>org.quartz-scheduler</groupId>
    42             <artifactId>quartz</artifactId>
    43             <version>2.2.1</version>
    44             <!-- 去除Quartz坐标自带的日志记录 -->
    45             <exclusions>
    46                 <exclusion>
    47                     <artifactId>slf4j-api</artifactId>
    48                     <groupId>org.slf4j</groupId>
    49                 </exclusion>
    50             </exclusions>
    51         </dependency>
    52         <!-- 添加Scheduled坐标,主要使用Cron定时时间 -->
    53         <dependency>
    54             <groupId>org.springframework</groupId>
    55             <artifactId>spring-context-support</artifactId>
    56         </dependency>
    57         <!-- Sprng tx事务坐标 -->
    58         <dependency>
    59             <groupId>org.springframework</groupId>
    60             <artifactId>spring-tx</artifactId>
    61         </dependency>
    62     </dependencies>
    63 
    64     <build>
    65         <plugins>
    66             <plugin>
    67                 <groupId>org.springframework.boot</groupId>
    68                 <artifactId>spring-boot-maven-plugin</artifactId>
    69             </plugin>
    70         </plugins>
    71     </build>
    72 
    73 </project>

    首先使用Quartz单独练习,看Quartz如何进行任务调度。

     1 package com.bie.springboot.job;
     2 
     3 import org.quartz.*;
     4 import org.quartz.impl.StdSchedulerFactory;
     5 
     6 import java.text.SimpleDateFormat;
     7 import java.util.Date;
     8 
     9 /**
    10  * 定义任务类
    11  */
    12 public class JobDemo implements Job {
    13 
    14     /**
    15      * 任务被触发时所执行的方法
    16      *
    17      * @param jobExecutionContext
    18      * @throws JobExecutionException
    19      */
    20     @Override
    21     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    22         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    23         System.out.println("任务调度器: " + sdf.format(new Date()));
    24     }
    25 
    26     public static void main(String[] args) throws SchedulerException {
    27         // 1、创建 Job 对象:你要做什么事?
    28         JobDetail job = JobBuilder.newJob(JobDemo.class).build();
    29 
    30         // 2、创建 Trigger 对象:在什么时间做?
    31         // 第一种,简单的trigger触发时间:通过 Quartz 提供一个方法来完成简单的重复 调用 cron。
    32         // 第二种,Trigger:按照 Cron 的表达式来给定触发的时间。
    33         Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2)).build();
    34 
    35         Trigger trigger2 = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();
    36         // 3、创建 Scheduler 对象:在什么时间做什么事?
    37         Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    38         scheduler.scheduleJob(job, trigger);
    39         // scheduler.scheduleJob(job, trigger2);
    40 
    41         // 启动
    42         scheduler.start();
    43     }
    44 
    45 }

    Spring Boot整合Quartz定时框架。Quartz配置类,完成Springboot对Quartz整合的配置信息。

     1 package com.bie.springboot.config;
     2 
     3 import com.bie.springboot.job.JobDemo;
     4 import org.springframework.context.annotation.Bean;
     5 import org.springframework.context.annotation.Configuration;
     6 import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
     7 import org.springframework.scheduling.quartz.JobDetailFactoryBean;
     8 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
     9 
    10 /**
    11  * Quartz配置类,完成Springboot对Quartz整合的配置信息
    12  */
    13 @Configuration
    14 public class QuartzConfig {
    15 
    16     /**
    17      * 第一步,创建Job对象。
    18      *
    19      * @return
    20      */
    21     @Bean
    22     public JobDetailFactoryBean jobDetailFactoryBean() {
    23         JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
    24         // 关联我们创建的Job类
    25         factoryBean.setJobClass(JobDemo.class);// 经过反射创建对象
    26         return factoryBean;
    27     }
    28 
    29     /**
    30      * 创建Trigger对象,简单的Trigger对象。
    31      *
    32      * @param jobDetailFactoryBean
    33      * @return
    34      */
    35 //    @Bean
    36 //    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
    37 //        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
    38 //        // 关联JobDetail对象
    39 //        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
    40 //        // 该参数表示一个执行的毫秒数
    41 //        factoryBean.setRepeatInterval(2000);
    42 //        // 重复次数
    43 //        factoryBean.setRepeatCount(5);
    44 //        return factoryBean;
    45 //    }
    46 
    47     /**
    48      * Cron Trigger
    49      *
    50      * @param jobDetailFactoryBean
    51      * @return
    52      */
    53     @Bean
    54     public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
    55         CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
    56         // 关联JobDetail对象
    57         factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
    58         // 设置触发时间
    59         factoryBean.setCronExpression("0/2 * * * * ?");
    60         return factoryBean;
    61     }
    62 
    63 
    64     /**
    65      * 第三步,创建Scheduler对象
    66      *
    67      * @param simpleTriggerFactoryBean
    68      * @return
    69      */
    70 //    @Bean
    71 //    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean) {
    72 //        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
    73 //        // 关联trigger
    74 //        factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
    75 //        return factoryBean;
    76 //    }
    77 
    78     /**
    79      * @param cronTriggerFactoryBean
    80      * @return
    81      */
    82     @Bean
    83     public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean) {
    84         SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
    85         // 关联trigger
    86         factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
    87         return factoryBean;
    88     }
    89 
    90 }

    Spring Boot整合Quartz,启动类。

     1 package com.bie.springboot;
     2 
     3 import org.springframework.boot.SpringApplication;
     4 import org.springframework.boot.autoconfigure.SpringBootApplication;
     5 import org.springframework.scheduling.annotation.EnableScheduling;
     6 
     7 /**
     8  * spring Boot整合Quartz
     9  */
    10 @SpringBootApplication
    11 @EnableScheduling // 开启时间调度
    12 public class SpringbootQuartzApplication {
    13 
    14     public static void main(String[] args) {
    15         SpringApplication.run(SpringbootQuartzApplication.class, args);
    16     }
    17 
    18 }

    运行效果,如下所示:

    Spring Boot定时任务,Job类对象注入,比如在Job的实现类里面要使用业务层下面某个对象里面的某个方法,就需要将业务层下面的对象注入到该Job实现类里面。

     1 package com.bie.springboot.service;
     2 
     3 import org.springframework.stereotype.Service;
     4 
     5 @Service
     6 public class UserService {
     7 
     8     public void show() {
     9         System.out.println("我喜好你啊,Springboot!");
    10     }
    11 
    12 }

    在定义的任务类中注入需要使用的业务层对象,进行方法调用。

     1 package com.bie.springboot.job;
     2 
     3 import com.bie.springboot.service.UserService;
     4 import org.quartz.*;
     5 import org.quartz.impl.StdSchedulerFactory;
     6 import org.springframework.beans.factory.annotation.Autowired;
     7 
     8 import java.text.SimpleDateFormat;
     9 import java.util.Date;
    10 
    11 /**
    12  * 定义任务类
    13  */
    14 public class JobDemo implements Job {
    15 
    16     @Autowired
    17     private UserService userService;
    18 
    19     /**
    20      * 任务被触发时所执行的方法
    21      *
    22      * @param jobExecutionContext
    23      * @throws JobExecutionException
    24      */
    25     @Override
    26     public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
    27         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    28         System.out.println("任务调度器: " + sdf.format(new Date()));
    29 
    30         // 调用业务层的方法。
    31         this.userService.show();
    32     }
    33 
    34     public static void main(String[] args) throws SchedulerException {
    35         // 1、创建 Job 对象:你要做什么事?
    36         JobDetail job = JobBuilder.newJob(JobDemo.class).build();
    37 
    38         // 2、创建 Trigger 对象:在什么时间做?
    39         // 第一种,简单的trigger触发时间:通过 Quartz 提供一个方法来完成简单的重复 调用 cron。
    40         // 第二种,Trigger:按照 Cron 的表达式来给定触发的时间。
    41         Trigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.repeatSecondlyForever(2)).build();
    42 
    43         Trigger trigger2 = TriggerBuilder.newTrigger().withSchedule(CronScheduleBuilder.cronSchedule("0/2 * * * * ?")).build();
    44         // 3、创建 Scheduler 对象:在什么时间做什么事?
    45         Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
    46         scheduler.scheduleJob(job, trigger);
    47         // scheduler.scheduleJob(job, trigger2);
    48 
    49         // 启动
    50         scheduler.start();
    51     }
    52 
    53 }

    启动主启动类,出现如下所示的错误,那么可以分析出JobDetailFactoryBean创建Job对象的时候是通过反射创建对象的,但是我们此时需要将所使用的对象都放到Spring的Ioc容器中才可以进行依赖。

     1   .   ____          _            __ _ _
     2  /\ / ___'_ __ _ _(_)_ __  __ _    
     3 ( ( )\___ | '_ | '_| | '_ / _` |    
     4  \/  ___)| |_)| | | | | || (_| |  ) ) ) )
     5   '  |____| .__|_| |_|_| |_\__, | / / / /
     6  =========|_|==============|___/=/_/_/_/
     7  :: Spring Boot ::        (v2.2.6.RELEASE)
     8 
     9 2020-05-22 10:25:39.490  INFO 12556 --- [           main] c.b.s.SpringbootQuartzApplication        : Starting SpringbootQuartzApplication on DESKTOP-V37QSSE with PID 12556 (D:programideaIntelliJ IDEA 2019.1.3workspace_ideaspringboot-quartz	argetclasses started by biehl in D:programideaIntelliJ IDEA 2019.1.3workspace_ideaspringboot-quartz)
    10 2020-05-22 10:25:39.494  INFO 12556 --- [           main] c.b.s.SpringbootQuartzApplication        : No active profile set, falling back to default profiles: default
    11 2020-05-22 10:25:41.160  INFO 12556 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
    12 2020-05-22 10:25:41.167  INFO 12556 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
    13 2020-05-22 10:25:41.168  INFO 12556 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.33]
    14 2020-05-22 10:25:41.244  INFO 12556 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
    15 2020-05-22 10:25:41.244  INFO 12556 --- [           main] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1648 ms
    16 2020-05-22 10:25:41.317  INFO 12556 --- [           main] org.quartz.impl.StdSchedulerFactory      : Using default implementation for ThreadExecutor
    17 2020-05-22 10:25:41.324  INFO 12556 --- [           main] org.quartz.core.SchedulerSignalerImpl    : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    18 2020-05-22 10:25:41.325  INFO 12556 --- [           main] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.2.1 created.
    19 2020-05-22 10:25:41.326  INFO 12556 --- [           main] org.quartz.simpl.RAMJobStore             : RAMJobStore initialized.
    20 2020-05-22 10:25:41.326  INFO 12556 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.2.1) 'schedulerFactoryBean' with instanceId 'NON_CLUSTERED'
    21   Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
    22   NOT STARTED.
    23   Currently in standby mode.
    24   Number of jobs executed: 0
    25   Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
    26   Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.
    27 
    28 2020-05-22 10:25:41.326  INFO 12556 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'schedulerFactoryBean' initialized from an externally provided properties instance.
    29 2020-05-22 10:25:41.326  INFO 12556 --- [           main] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.2.1
    30 2020-05-22 10:25:41.327  INFO 12556 --- [           main] org.quartz.core.QuartzScheduler          : JobFactory set to: org.springframework.scheduling.quartz.AdaptableJobFactory@620aa4ea
    31 2020-05-22 10:25:41.468  INFO 12556 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
    32 2020-05-22 10:25:41.596  INFO 12556 --- [           main] o.s.s.c.ThreadPoolTaskScheduler          : Initializing ExecutorService 'taskScheduler'
    33 2020-05-22 10:25:41.621  INFO 12556 --- [           main] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now
    34 2020-05-22 10:25:41.621  INFO 12556 --- [           main] org.quartz.core.QuartzScheduler          : Scheduler schedulerFactoryBean_$_NON_CLUSTERED started.
    35 2020-05-22 10:25:41.653  INFO 12556 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
    36 2020-05-22 10:25:41.656  INFO 12556 --- [           main] c.b.s.SpringbootQuartzApplication        : Started SpringbootQuartzApplication in 2.729 seconds (JVM running for 4.369)
    37 任务调度器: 2020-05-22 10:25:42
    38 2020-05-22 10:25:42.012 ERROR 12556 --- [ryBean_Worker-1] org.quartz.core.JobRunShell              : Job DEFAULT.jobDetailFactoryBean threw an unhandled Exception: 
    39 
    40 java.lang.NullPointerException: null
    41     at com.bie.springboot.job.JobDemo.execute(JobDemo.java:31) ~[classes/:na]
    42     at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
    43     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
    44 
    45 2020-05-22 10:25:42.013 ERROR 12556 --- [ryBean_Worker-1] org.quartz.core.ErrorLogger              : Job (DEFAULT.jobDetailFactoryBean threw an exception.
    46 
    47 org.quartz.SchedulerException: Job threw an unhandled exception.
    48     at org.quartz.core.JobRunShell.run(JobRunShell.java:213) ~[quartz-2.2.1.jar:na]
    49     at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573) [quartz-2.2.1.jar:na]
    50 Caused by: java.lang.NullPointerException: null
    51     at com.bie.springboot.job.JobDemo.execute(JobDemo.java:31) ~[classes/:na]
    52     at org.quartz.core.JobRunShell.run(JobRunShell.java:202) ~[quartz-2.2.1.jar:na]
    53     ... 1 common frames omitted

    解决方法,重写继承AdaptableJobFactory的类,重写其方法,将对象注入到Ioc容器中。

     1 package com.bie.springboot.utils;
     2 
     3 import org.quartz.spi.TriggerFiredBundle;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
     6 import org.springframework.scheduling.quartz.AdaptableJobFactory;
     7 import org.springframework.stereotype.Component;
     8 
     9 /**
    10  * 重写继承AdaptableJobFactory的类,重写其方法,将对象注入到Ioc容器中。
    11  */
    12 @Component("myAdaptableJobFactory")
    13 public class MyAdaptableJobFactory extends AdaptableJobFactory {
    14 
    15     //AutowireCapableBeanFactory 可以将一个对象添加到 SpringIOC 容器中, 并且完成该对象注入
    16     @Autowired
    17     private AutowireCapableBeanFactory autowireCapableBeanFactory;
    18 
    19     /**
    20      * 该方法需要将实例化的任务对象手动的添加到 spring Ioc 容器中并且完成对 象的注入
    21      *
    22      * @param bundle
    23      * @return
    24      * @throws Exception
    25      */
    26     @Override
    27     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
    28         Object obj = super.createJobInstance(bundle);
    29         // 将 obj 对象添加 Spring IOC 容器中,并完成注入
    30         this.autowireCapableBeanFactory.autowireBean(obj);
    31         return obj;
    32     }
    33 
    34 }

    修改 QuartzConfig 类schedulerFactoryBean方法。

     1 package com.bie.springboot.config;
     2 
     3 import com.bie.springboot.job.JobDemo;
     4 import com.bie.springboot.utils.MyAdaptableJobFactory;
     5 import org.springframework.context.annotation.Bean;
     6 import org.springframework.context.annotation.Configuration;
     7 import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
     8 import org.springframework.scheduling.quartz.JobDetailFactoryBean;
     9 import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    10 
    11 /**
    12  * Quartz配置类,完成Springboot对Quartz整合的配置信息
    13  */
    14 @Configuration
    15 public class QuartzConfig {
    16 
    17     /**
    18      * 第一步,创建Job对象。
    19      *
    20      * @return
    21      */
    22     @Bean
    23     public JobDetailFactoryBean jobDetailFactoryBean() {
    24         JobDetailFactoryBean factoryBean = new JobDetailFactoryBean();
    25         // 关联我们创建的Job类
    26         factoryBean.setJobClass(JobDemo.class);
    27         return factoryBean;
    28     }
    29 
    30     /**
    31      * 创建Trigger对象,简单的Trigger对象。
    32      *
    33      * @param jobDetailFactoryBean
    34      * @return
    35      */
    36 //    @Bean
    37 //    public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
    38 //        SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean();
    39 //        // 关联JobDetail对象
    40 //        factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
    41 //        // 该参数表示一个执行的毫秒数
    42 //        factoryBean.setRepeatInterval(2000);
    43 //        // 重复次数
    44 //        factoryBean.setRepeatCount(5);
    45 //        return factoryBean;
    46 //    }
    47 
    48     /**
    49      * Cron Trigger
    50      *
    51      * @param jobDetailFactoryBean
    52      * @return
    53      */
    54     @Bean
    55     public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetailFactoryBean jobDetailFactoryBean) {
    56         CronTriggerFactoryBean factoryBean = new CronTriggerFactoryBean();
    57         // 关联JobDetail对象
    58         factoryBean.setJobDetail(jobDetailFactoryBean.getObject());
    59         // 设置触发时间
    60         factoryBean.setCronExpression("0/2 * * * * ?");
    61         return factoryBean;
    62     }
    63 
    64 
    65     /**
    66      * 第三步,创建Scheduler对象
    67      *
    68      * @param simpleTriggerFactoryBean
    69      * @return
    70      */
    71 //    @Bean
    72 //    public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactoryBean) {
    73 //        SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
    74 //        // 关联trigger
    75 //        factoryBean.setTriggers(simpleTriggerFactoryBean.getObject());
    76 //        return factoryBean;
    77 //    }
    78 
    79     /**
    80      * @param cronTriggerFactoryBean
    81      * @return
    82      */
    83     @Bean
    84     public SchedulerFactoryBean schedulerFactoryBean(CronTriggerFactoryBean cronTriggerFactoryBean, MyAdaptableJobFactory myAdaptableJobFactory) {
    85         SchedulerFactoryBean factoryBean = new SchedulerFactoryBean();
    86         // 关联trigger
    87         factoryBean.setTriggers(cronTriggerFactoryBean.getObject());
    88         // 设置JobFactory
    89         factoryBean.setJobFactory(myAdaptableJobFactory);
    90         return factoryBean;
    91     }
    92 
    93 }

    实现效果,如下所示:

  • 相关阅读:
    ubuntu12.04 死机 卡屏 画面冻结解决方案
    Install Firefox 20 in Ubuntu 13.04, Ubuntu 12.10, Ubuntu 12.04, Linux Mint 14 and Linux Mint 13 by PPA
    ListView1.SelectedItems.Clear()
    android studio 下载地址
    jquery.slider.js jquery幻灯片测试
    jquery.hovermenu.js
    jquery.tab.js选项卡效果
    适配 placeholder,jquery版
    jquery.autoscroll.js jquery自动滚动效果
    将 Google Earth 地图集成到自己的窗体上的 简单控件
  • 原文地址:https://www.cnblogs.com/biehongli/p/12930945.html
Copyright © 2011-2022 走看看