Quartz介绍

Quartz是Job scheduling(作业调度)领域的一个开源项目,Quartz既可以单独使用也可以跟spring框
架整合使用,在实际开发中一般会使用后者。使用Quartz可以开发一个或者多个定时任务,每个定时任
务可以单独指定执行的时间,例如每隔1小时执行一次、每个月第一天上午10点执行一次、每个月最后
一天下午5点执行一次等。
官网:http://www.quartz-scheduler.org/

简单使用(使用步奏与解释在代码注释中)

搭建maven工程

springboot如何设置每分钟执行一次和每小时执行一次 spring 定时器每小时执行一次_自定义

pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.fs</groupId>
    <artifactId>QuartzDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
<!--        spring-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>
<!--        quartz 定时器-->
        <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>
    </dependencies>
</project>
applicationContext-jobs.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">



    <!--    把自定义的定时任务类(这个类是个普通类,里面需要自己编写定时执行的方法)springIOC管理-->
    <bean id="quartzHelloWorld" class="com.fs.regularwork.QuartzHelloWorld">
    </bean>
<!--    设置第二个定时类-->
    <bean id="quartzHelloWorld02" class="com.fs.regularwork.QuartzHelloWorld02"></bean>



<!--    将方法调用作业详细信息工厂Bean交给ioc管理-->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<!--        注入自定义的定时任务类的对象-->
        <property name="targetObject" ref="quartzHelloWorld"/>
<!--        注入自定义调用对象的具体执行的方法-->
        <property name="targetMethod" value="quartzTest"/>
    </bean>
    <!--    将方法调用作业详细信息工厂Bean交给ioc管理-->
    <bean id="jobDetail02" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
        <!--        注入自定义的定时任务类的对象-->
        <property name="targetObject" ref="quartzHelloWorld02"/>
        <!--        注入自定义调用对象的具体执行的方法-->
        <property name="targetMethod" value="quartzTest02"/>
    </bean>



<!--    注册一个触发器,指定任务触发时间,触发上面指定的方法-->
    <bean id="myTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<!--        注入jobDetail,通过反射来调用我们上面自定义的方法-->
        <property name="jobDetail" ref="jobDetail"/>
<!--        指定触发事件,基于Cron表达式-->
        <property name="cronExpression">
<!--            从0秒开始,每10秒执行一次,测试功能使用-->
            <value>0/10 * * * * ? </value>
<!--            从每天的3点开始执行一次-->
<!--            <value>0 0 3 * * ? </value>-->
<!--        从0小时开始,30分钟执行一次    -->
<!--            <value>0 0/30 * * * ?</value>-->
        </property>
    </bean>
    <!--    注册一个触发器,指定任务触发时间,触发上面指定的方法-->
    <bean id="myTrigger02" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!--        注入jobDetail,通过反射来调用我们上面自定义的方法-->
        <property name="jobDetail" ref="jobDetail02"/>
        <property name="cronExpression">
            <value>0/10 * * * * ? </value>
        </property>
    </bean>




<!--  统一注册一个调度工厂,通过这个调用工厂调度触发器任务  -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<!--        可以注入多个触发器-->
        <property name="triggers">
            <list>
<!--                注入上面触发器,可以注入多个,我由于上面配置了2个,所以我注入2个测试能否10秒执行方法-->
                <ref bean="myTrigger"/>
                <ref bean="myTrigger02"/>
            </list>
        </property>
    </bean>
</beans>
java config方式(伪代码)
package com.fs.config;

import com.fs.controller.JorumServerRegister;
import org.quartz.JobDetail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

@Configuration
public class QuartzConfig {

    //注入统一任务类
    @Autowired
    private 任务类 jorumServerRegister;

    @Bean("heartbeat")
    public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(){
        MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean = new MethodInvokingJobDetailFactoryBean();
        //注入自定义的定时任务类的对象
        methodInvokingJobDetailFactoryBean.setTargetObject(jorumServerRegister);
        //注入自定义调用对象的具体执行的方法
        methodInvokingJobDetailFactoryBean.setTargetMethod("heartbeat");

        return methodInvokingJobDetailFactoryBean;
    }

    //触发器
    @Bean
    public CronTriggerFactoryBean cronTriggerFactoryBean(@Autowired @Qualifier("heartbeat") MethodInvokingJobDetailFactoryBean heartbeat){
        CronTriggerFactoryBean cronTriggerFactoryBean = new CronTriggerFactoryBean();
        // 注入jobDetail,通过反射来调用我们上面自定义的方法
        JobDetail object = heartbeat.getObject();
        cronTriggerFactoryBean.setJobDetail(object);
        //10秒执行一次心跳方法
        cronTriggerFactoryBean.setCronExpression("0/10 * * * * ? ");

        return cronTriggerFactoryBean;
    }

    //注册一个统一调度工厂
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean(@Autowired CronTriggerFactoryBean cronTriggerFactoryBean){
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        //注入上面触发器
        schedulerFactoryBean.setTriggers(cronTriggerFactoryBean.getObject());

        return schedulerFactoryBean;
    }
}
cron表达式

上面的入门案例中我们指定了一个表达式:0/10 * * * * ?

这种表达式称为cron表达式,通过cron表达式可以灵活的定义出符合要求的程序执行的时间。本小节我

们就来学习一下cron表达式的使用方法。如下图:

springboot如何设置每分钟执行一次和每小时执行一次 spring 定时器每小时执行一次_触发器_02


cron表达式分为七个域,之间使用空格分隔。其中最后一个域(年)可以为空。每个域都有自己允许的

值和一些特殊字符构成。使用这些特殊字符可以使我们定义的表达式更加灵活。

下面是对这些特殊字符的介绍:

逗号(,):指定一个值列表,例如使用在月域上1,4,5,7表示1月、4月、5月和7月

横杠(-):指定一个范围,例如在时域上3-6表示3点到6点(即3点、4点、5点、6点)

星号(*):表示这个域上包含所有合法的值。例如,在月份域上使用星号意味着每个月都会触发

斜线(/):表示递增,例如使用在秒域上0/15表示每15秒

问号(?):只能用在日和周域上,但是不能在这两个域上同时使用。表示不指定

井号(#):只能使用在周域上,用于指定月份中的第几周的哪一天,例如6#3,意思是某月的第三个

周五 (6=星期五,3意味着月份中的第三周)

L:某域上允许的最后一个值。只能使用在日和周域上。当用在日域上,表示的是在月域上指定的月份

的最后一天。用于周域上时,表示周的最后一天,就是星期六

W:W 字符代表着工作日 (星期一到星期五),只能用在日域上,它用来指定离指定日的最近的一个工作


cron表达式在线生成网站

前面介绍了cron表达式,但是自己编写表达式还是有一些困难的,我们可以借助一些cron表达式在线生
成器来根据我们的需求生成表达式即可。
cron表达式在线生成

QuartzHelloWorld
package com.fs.regularwork;

import java.text.SimpleDateFormat;
import java.util.Date;
/*
自定义的普通类,让Quartz 通过反射来定时执行这个方法
 */
public class QuartzHelloWorld {
    //编写定时执行的方法,注意要是public的
    public void quartzTest(){
        System.out.println("02:HelloWorld_Quartz"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));
    }
}
QuartzHelloWorld02
package com.fs.regularwork;

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

/*
自定义的普通类,让Quartz 通过反射来定时执行这个方法
 */
public class QuartzHelloWorld02 {
    //编写定时执行的方法,注意要是public的
    public void quartzTest02(){
        System.out.println("01:HelloWorld_Quartz"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date().getTime()));
    }
}
TestQuartz测试类
package com.fs.regularwork;

import org.springframework.context.support.ClassPathXmlApplicationContext;
/*
测试Quartz
 */
public class TestQuartz {
    public static void main(String[] args) {
        //只有创建了spring的容器,定时器就会去反射通过我们xml配置的cron表达式指定的时间去调用我们配置的方法
        new ClassPathXmlApplicationContext("classpath:applicationContext-jobs.xml");
    }
}
运行结果

springboot如何设置每分钟执行一次和每小时执行一次 spring 定时器每小时执行一次_spring_03