SpringBoot整合Quartz

Lou.Chen
大约 4 分钟

Springboot整合Quartz

一、什么是Quartz

Quartzopen in new window官网上是这么写的

1、Quartz 是一个完全由 Java 编写的开源作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。 2、Quartz 可以与 J2EE 与 J2SE 应用程序相结合也可以单独使用。 3、Quartz 允许程序开发人员根据时间的间隔来调度作业。 4、Quartz 实现了作业和触发器的多对多的关系,还能把多个作业与不同的触发器关联。

二、Quartz核心概念

1、Job 表示一个工作,要执行的具体内容。 2、JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。 3、Trigger 代表一个调度参数的配置,什么时候去调。 4、Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。

三、基本配置使用

1、pom.xml

spring-boot-starter-quartz

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.lc</groupId>
    <artifactId>quartz</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>quartz</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-quartz</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2、启用定时任务
@SpringBootApplication
//启动定时任务
@EnableScheduling
public class QuartzApplication {

    public static void main(String[] args) {
        SpringApplication.run(QuartzApplication.class, args);
    }

}

3、job任务配置
①直接定义一个Bean作为任务
  1. 首先将这个 Job 注册到 Spring 容器中。
  2. 这种定义方式有一个缺陷,就是无法传参。
@Component
public class MyFirstJob {
    /**
     * 这种方式配置的任务不支持传参
     */
    public void sayHello() {
        System.out.println("first job say hello:"+new Date());
    }
}
②继承 QuartzJobBean 并实现默认的方法

这种方式支持传参,任务启动时,executeInternal 方法将会被执行。

public class MySecondJob extends QuartzJobBean {

    /**
     * 给当前job传入参数
     */
    private String name;

    public MySecondJob setName(String name) {
        this.name = name;
        return this;
    }

    /**
     * 这种形式的job支持传参
     * @param jobExecutionContext
     * @throws JobExecutionException
     */
    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("second job say hello:"+name+":"+new Date());
    }
}

4、JobDetail和Trigger配置

JobDetail(要做的事情),另一个是触发器(什么时候做)

@Configuration
public class QuartzConfig {

    /**
     * 配置job实例
     * MethodInvokingJobDetailFactoryBean配置的任务不能传输参数
     * @return
     */
    @Bean
    MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean() {
        MethodInvokingJobDetailFactoryBean bean=new MethodInvokingJobDetailFactoryBean();
//        设置job所在的类名 (类名开头小写)
        bean.setTargetBeanName("myFirstJob");
//        设置指定job方法名
        bean.setTargetMethod("sayHello");
        return bean;
    }

    /**
     * 配置job实例
     *JobDetailFactoryBean 可以设置job参数
     * @return
     */
    @Bean
    JobDetailFactoryBean jobDetailFactoryBean() {
        JobDetailFactoryBean bean=new JobDetailFactoryBean();
//        向job传入参数
        JobDataMap dataMap=new JobDataMap();
        dataMap.put("name", "lccc");
        bean.setJobDataMap(dataMap);
//        设置该job所在的class对象
//        此job因为实现QuartzJobBean类所以自动实现内部的执行executeInternal方法完成任务
        bean.setJobClass(MySecondJob.class);
        return bean;
    }

    /**
     * 配置简单的触发器(执行时间规则)
     * @return
     */
    @Bean
    SimpleTriggerFactoryBean simpleTriggerFactoryBean() {
        SimpleTriggerFactoryBean bean=new SimpleTriggerFactoryBean();
//        将job对象和触发器绑定
        bean.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());
//        job开启的时间  --当前时间
        bean.setStartTime(new Date());
//        job重复间隔
        bean.setRepeatInterval(2000);
//        job执行次数
        bean.setRepeatCount(3);
        return bean;
    }

    /**
     *配置cron表达式
     * @return
     */
    @Bean
    CronTriggerFactoryBean cronTriggerFactoryBean() {
        CronTriggerFactoryBean bean=new CronTriggerFactoryBean();
//        绑定job任务和触发器对象
        bean.setJobDetail(jobDetailFactoryBean().getObject());
//        设置cron表达式
//        每秒执行一次
        bean.setCronExpression("* * * * * ?");
        return bean;
    }


    /**
     * 配置调度任务
     * @return
     */
    @Bean
    SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean bean=new SchedulerFactoryBean();
//       向调度任务中加入配置好的触发器和job对象
        bean.setTriggers(simpleTriggerFactoryBean().getObject(),cronTriggerFactoryBean().getObject());
        return bean;
    }


}

5、配置解释

关于这个配置说如下几点:

  • JobDetail 的配置有两种方式:MethodInvokingJobDetailFactoryBean 和 JobDetailFactoryBean 。

  • 使用 MethodInvokingJobDetailFactoryBean 可以配置目标 Bean 的名字和目标方法的名字,这种方式不支持传参。

  • 使用 JobDetailFactoryBean 可以配置 JobDetail ,任务类继承自 QuartzJobBean ,这种方式支持传参,将参数封装在 JobDataMap 中进行传递。

  • Trigger 是指触发器,Quartz 中定义了多个触发器,这里向大家展示其中两种的用法,SimpleTrigger 和 CronTrigger 。

  • SimpleTrigger 有点类似于前面说的 @Scheduled 的基本用法。

  • CronTrigger 则有点类似于 @Scheduled 中 cron 表达式的用法。