Spring integrates Quartz to implement a simple timing task

        In the process of our software project development, I believe you will encounter the following business scenarios at many times: generate corresponding business reports every day, every week or every month; count the number of people registered in the system every day; regularly clean up users who have not logged in to the platform for a long time, etc. Wait. How to deal with this kind of business scenario? Manually go to the database to perform statistics? Don't be kidding, there is no need for people to do this kind of thing. If tasks like this require someone to do statistics every day, then many people are probably going crazy. For this kind of business situation, the use of timed tasks is a very good choice. In the Java field, there are many open source tools for timing tasks, ranging from a Timer class to the Quartz framework. In general, I prefer Quartz, which is powerful and easy to use. Next we will look at how to implement timing tasks in business systems through Spring and Quartz.

Spring integrates Quartz to implement timing tasks. The steps are very simple. It generally needs to go through the following steps: create a task (Job), configure JobDetail, configure triggers (Trigger), configure SchedulerFactoryBean

1.Maven creates a Springboot project and introduces Spring and quartz dependencies

<?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.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>spring-quartz2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-quartz2</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-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>3.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.2.4.RELEASE</version>
        </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>

1. Create 2 task classes (Job)

   Inherit the implements interface to implement this form of the Job class, create a task class MyJob1, and implement the abstract method execute inside

package com.example.job;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 定时任务MyJob1
 * @author: wangxiaobo
 * @create: 2020-09-04 12:26
 **/
public class MyJob1 implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Date date = new Date ();
        SimpleDateFormat sf  = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        JobDataMap dataMap = context.getJobDetail ().getJobDataMap ();
        System.out.println (""+sf.format (date)+"任务1执行了,"+dataMap.getString ("gupao"));
    }
}

  Inherit the implements interface to implement this form of the Job class, create a task class MyJob2, and implement the abstract method execute inside

package com.example.job;

import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.text.SimpleDateFormat;
import java.util.Date;

/**定时任务MyJob2
  *
 * @author: wangxiaobo
 * @create: 2020-09-04 12:48
 **/
public class MyJob2 implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        Date date = new Date ();
        SimpleDateFormat sf  = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss");
        JobDataMap dataMap = context.getJobDetail ().getJobDataMap ();
        System.out.println (""+sf.format (date)+"任务2执行了,"+dataMap.getString ("gupao"));
    }
}

For the convenience of demonstration, there is no complicated business logic written in the executeInternal method, only a single sentence is output, and the business logic you need can be implemented in this method in a real production environment.

2. Configure JobDetailFactoryBean in the spring-quartz.xml configuration file

 <!-- 1:定义任务的bean , 这里使用MethodInvokingJobDetailFactoryBean,也可以使用JobDetailFactoryBean-->
<bean name="myJob1" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <!-- 指定job的名称 -->
    <property name="name" value="my_job_1"/>
    <!-- 指定job的分组 -->
    <property name="group" value="my_group"/>
    <!-- 指定具体的job类 -->
    <property name="jobClass" value="com.example.job.MyJob1"/>
    <!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中会删除任务 -->
    <property  name="durability" value="true"/>

</bean>
    <bean name="myJob2" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <!-- 指定job的名称 -->
        <property name="name" value="my_job_2"/>
        <!-- 指定job的分组 -->
        <property name="group" value="my_group"/>
        <!-- 指定具体的job类 -->
        <property name="jobClass" value="com.example.job.MyJob2"/>
        <!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中会删除任务 -->
        <property name="durability" value="true"/>

    </bean>

Three, configure the trigger (Trigger)

Spring provides two kinds of triggers, as follows:
1. org.springframework.scheduling.quartz.SimpleTriggerFactoryBean (this method is triggered once every 24 hours, for example)
2. org.springframework.scheduling .quartz.CronTriggerFactoryBean (This method is triggered at a specified time, such as only on Monday. However, it is also very convenient to implement timing tasks similar to SimpleTriggerFactoryBean according to the configuration)
The two trigger methods provided by Spring and the previous The mentioned task creation methods can be mixed with each other, which is very flexible.
Here we first use SimpleTriggerFactoryBean this trigger to configure

 <!-- 2.1:定义触发器的bean。定义Simple的Trigger,一个触发器只能和一个任务绑定 -->
    <!-- 一个Job可以绑定多个Trigger-->
    <bean name="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <!--指定Trigger的名称 -->
        <property name="name" value="my_trigger_1"/>
        <!-- 指定Trigger的组别-->
        <property name="group" value="my_group"/>
        <!-- 指定Trigger绑定的job类 -->
        <property name="jobDetail" ref="myJob1"/>
        <!-- 指定Trigger的延迟时间为1s 后运行-->
        <property name="startDelay" value="1000"/>
        <!-- 指定Trigger的重复间隔5s-->
        <property name="repeatInterval" value="5000"/>
        <!-- 指定Trigger的重复次数 -->
        <property name="repeatCount" value="2"/>
    </bean>
    <!-- 2.2:定义触发器的bean。定义Cron的Trigger,一个触发器只能和一个任务绑定 -->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!--指定Trigger的名称 -->
        <property name="name" value="my_trigger_2"/>
        <!--指定Trigger的名称 -->
        <property name="group" value="my_group"/>
        <!-- 指定Trigger绑定的job类 -->
        <property name="jobDetail" ref="myJob2"/>
        <!--指定Cron的表达试,当前是每隔10s运行一次 -->
        <property name="cronExpression" value="0/10 * * * * ?"/>
    </bean>

Fourth, configure the SchedulerFactoryBean

<!--3.1 定义调度器。并将Trigger注册到调度器中,这种方式。任务朱慧存储到RAM -->
    <bean name="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
      <property  name="triggers">
          <list>
              <ref bean="simpleTrigger"/>
              <ref bean="cronTrigger"/>
          </list>
      </property>
    </bean>

Okay, after the configuration, let's start the program again to see if the timing tasks are running well (the Trigger we use here are two kinds of CronTriggerFactoryBean, or SimpleTriggerFactoryBean)

Start test effect:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @author: wangxiaobo
 * @create: 2020-09-04 13:30
 **/
public class QuartzTest {
    private  static Scheduler scheduler;

    public static void main(String[] args) throws SchedulerException{
        //获取容器
        ApplicationContext ac = new ClassPathXmlApplicationContext ("spring-quartz.xml");
        //从容器中获取调度器
        scheduler = (Scheduler) ac.getBean (" scheduler");
        //启动调度器
        scheduler.start ();
    }
}

   

 You can see that the timing task is running normally and achieve the effect we need

Guess you like

Origin blog.csdn.net/qq_34709784/article/details/108404241