Quartz框架 之 自学杂记(一)

Quartz框架

简介:一个开源的作业调度框架,比较简单灵活。它可以使用在web工程中,也可以在java简单工程中直接使用。

spring框架中也整合了此框架,org.springframework.scheduling.quartz


1、主要API

  1. Job:作业,任务具体实现
  2. JobDetail:作业细节,制定作业名等
  3. Trigger:触发器,定义作业触发时间
  4. scheduler:任务调度器

2、配置maven

引入quartz框架的jar包

        <!-- quartz 框架 自动任务调度 -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.2.3</version>
        </dependency>
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz-jobs</artifactId>
            <version>2.2.3</version>
        </dependency>

如果还有使用spring整合quartz框架配置方式,则还要引入上下文支持:

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context-support</artifactId>  
            <version>4.0.2.RELEASE</version>  
        </dependency> 

3、简单实例

quartz框架的实现可以直接编程式,也可以整合spring配置方式实现。

  1. 编程式实现
  2. 配置式实现

3.1、编程式实现

3.1.1、Job类

通过实现org.quartz.Job接口

package com.wm.spring.quartz;

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

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

public class MyJob implements Job{

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        //context 是作业调度上下文,可以从中获取作业细节名、触发器名等信息
        JobDetail jobDetail = context.getJobDetail();

        //作业名
        String name = jobDetail.getKey().getName();

        // 触发器名
        String triggerName = context.getTrigger().getKey().getName();


        System.out.println("jobDetail.getKey().getName: "+name);

        System.out.println("context.getTrigger().getKey().getName: "+triggerName);

        System.out.println("MyJob ....... " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }

}

实现Job接口,编写public void execute(JobExecutionContext context)方法。
在启动Job时,它会自动运行execute方法。


3.1.2、简单的测试

3.1.2.1、简单的触发器

simpleSchedule

package com.wm.spring.quartz;

import org.quartz.JobDetail;
import org.quartz.Trigger;
import org.quartz.Scheduler;
import org.quartz.impl.StdSchedulerFactory;
import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.CronScheduleBuilder.*;

public class SimpleScheduler {

    public static void main(String[] args) throws Exception {

        // 获取 作业调度器
        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();

        // 定义 作用细节
        JobDetail job = newJob(MyJob.class)
                        .withIdentity("job1", "group1")
                        .build();

        // 定义 触发器
        Trigger trigger = newTrigger()
                            .withIdentity("trigger1", "group1")
                            .startNow() // 现在运行
                            .withSchedule(simpleSchedule() // 定义调度器
                                            .withIntervalInSeconds(10) //定义 循环时间 每10S运行一次
                                            .repeatForever()) // 永远重复
                            .build();

        scheduler.scheduleJob(job, trigger); // 注册作用 和 调度器
        scheduler.start(); // 任务调度器 开启

    }

}

3.1.2.2、cron触发器

cronSchedule

// 定义 作用细节
        JobDetail job2 = newJob(MyJob.class)
                        .withIdentity("job2", "group2")
                        .build();


        Trigger trigger2 = newTrigger()
                            .withIdentity("trigger2", "group2")
                            .startNow()
                            .withSchedule(cronSchedule("0/5 * * * * ?")) // cron 表达式
                            .build();

        scheduler.scheduleJob(job2, trigger2); // 注册作用 和 调度器


        scheduler.start(); // 任务调度器 开启

3.1.2.3、结果

简单触发器:
job 每隔10s运行一次

这里写图片描述


cron触发器

job2 每隔5s触发一次

这里写图片描述


3.1.3、注意


在使用编程式实现时,如果发现newTrigger()、newJob(class) 、simpleSchedule()、cronSchedule()等静态方法不能使用时,则是因为 没有导入 静态包

import static org.quartz.JobBuilder.*;
import static org.quartz.TriggerBuilder.*;
import static org.quartz.SimpleScheduleBuilder.*;
import static org.quartz.CronScheduleBuilder.*;

一定要导入静态包,否则不能实现。
是因为 quartz框架2.x以后版本都是使用这种方法,它把实现触发器和作业细节都使用静态方式来的

如果你是使用的1.x,则不存在这个问题,并且获取的方式都不是使用这种静态方法的方式,而是直接可以new出来。


3.2、配置式方式

在spring容器中进行整合quartz框架

3.2.1、配置文件

spring-quartz.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" 
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd 
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd 
            http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context-4.0.xsd 
            http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
            http://www.springframework.org/schema/tx 
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">


    <bean id="myJob" class="com.wm.spring.quartz.MyJob" />

    <!-- 定义 作业细节 Job Detail -->
    <bean id="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
        <!-- 注入 Job 作业 -->
        <property name="jobClass" value="com.wm.spring.quartz.MyJob" />
        <property name="durability" value="true" />
    </bean>

    <!-- 定义 简单触发器  -->
    <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
        <!-- 注入 作业细节 JobDetail -->
        <property name="jobDetail" ref="myJobDetail" />
        <!-- 设置重复时间 2000ms -->
        <property name="repeatInterval" value="2000" />
        <!-- 设置 开始延迟时间 -->
        <property name="startDelay" value="0" />
    </bean>


    <!-- 定义 cron 触发器-->
    <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
        <!-- 定义作业细节 -->
        <property name="jobDetail" ref="myJobDetail" />
        <!-- 定义 cron 表达式 (秒 分 时 日 月 周 年) -->
        <property name="cronExpression" value="0/5 * * * * ?" />
    </bean>

    <!-- 定义 任务调度器工厂 -->
    <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <!-- 绑定触发器  -->
        <property name="triggers">
            <list>
                <ref bean="cronTrigger"/>
                <ref bean="simpleTrigger"/>
            </list>
        </property>
    </bean>

</beans>            

这里面配置了两种方式:简单触发器、cron触发器。

在加载配置文件时,作业调度器就会自动启动,并且根据触发器的触发时间去调用Job作业里具体的实现。

注:如果提示:SchedulerFactoryBean、CronTriggerFactoryBean、SimpleTriggerFactoryBean、JobDetailFactoryBean等,这些无法实现,则说明是因为spring框架中没有加入上下文支持jar

Maven pom.xml配置如下:

        <dependency>  
            <groupId>org.springframework</groupId>  
            <artifactId>spring-context-support</artifactId>  
            <version>4.0.2.RELEASE</version>  
        </dependency> 

3.2.2、测试类

QuartzMainTest.java

package com.wm.spring.TEST;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class QuartzMainTest {

    public static void main(String[] args) {

        new ClassPathXmlApplicationContext("spring-quartz.xml");
    }

}

在加载配置文件后,任务调度器就会自动启动,再根据触发器配置的触发时间 去执行 作业。


3.2.3、结果

simpleTrigger:每隔2000ms(2s)执行一次
cronTrigger : 每隔5s执行一次

这里写图片描述


4、CronExpression

cron表达式包括7个字段:

(秒 分 时 日 月 周 年)

  1. 秒 (0~59) -,*,/
  2. 分 (0~59) -,*,/
  3. 时 (0~23) -,*,/
  4. 日 (0~31) -,*,/,?,L,W,C
  5. 月 (1~12) -,*,/,(JAN~DEC)
  6. 周/星期 (1~7),-,*,/,?,(SUN~SAT),L,C
  7. 年 (可选)1970~2099 -,*,/

4.1、特殊符号

-,*,/,?,,,W,C,L,#

4.1.1、星号(*)

使用星号(*) 指示着你想在这个域上包含所有合法的值。

如: (* 30 2 * * ?),表示:每一天的2点30分-31分之间的每一秒都运行一次


4.1.2、中划线(-)

中划线 (-) 用于指定一个范围。

如:(0 30-33 2 * * ?),表示: 每一天的2点30、31、32、33分的时候执行


4.1.3、反斜线(/)

斜杠 (/) 是用于时间表的递增的。n/m表示从n开始,每次增加m

如:(0/2 * * * * ?),表示:每隔两秒运行一次
(0 0/5 * * * ?),表示:每隔五分钟运行一次


4.1.4、问号(?)

? 号只能用在日和周域上,但是不能在这两个域上同时使用,表示不确定的值。

它不同于星号,星号是指示着该域上的每一个值。? 是说不为该域指定值。

它不能在日和周域上同时指定的原因是 容易引起模拟两可的意义。
如:如果在日域上是3,在周域上是3,那它表示是什么呢?是每个月的3号又刚好是星期二??还是说每周二的3号执行?
所以要排除这种不明确的可能性。

只要记住,假如你为这两域的其中一个指定了值,那就必须在另一个字值上放一个 ?。

如:(0 13 2 1 * ?),表示:每个月的1号的2:13执行
(0 13 2 ? * 3),表示:每周二的2:13执行


4.1.5、井号(#)

表示该月第几个周X,只能用于周域。6#3表示该月第3个周五

如:(0 30 2 ? * 4#2),表示这个月的第二个周三的2:30执行


4.1.6、逗号(,)

逗号 (,) 是用来在给某个域上指定一个值列表的。

如:(0 30 2,3,4 ? * *),表示:每天的2:30、3:30、4:30的时候执行


4.1.7、字母(L、W、C)

字母L

在日表示一个月中的最后一天,用在周表示该月最后一个星期X

如:(0 30 4 L * ?),表示:每一个月的最后一天的4:30执行
(0 30 4 ? * L),表示:每一个月的最后一个星期六的4:30执行
(0 30 4 ? * 3L),表示:每月的最后一个星期二的4:30执行

字母W

表示离给定日期最近的工作日(周一到周五),W 字符代表着平日 (Mon-Fri),并且仅能用于日域中。

如:(0 30 2 15W * ?),如果这个月第15天是周六,那么触发器将会在这个月第14天即周五触发;如果这个月第15天是周日,那么触发器将会在这个月第16 天即周一触发;如果这个月第15天是周二,那么就在触发器这天触发。注意一点:这个用法只会在当前月计算值,不会越过当前月。

字母C

指和calendar联系后计算过的值。例:在day-of-month 字段用“5C”指在这个月第5天或之后包括calendar的第一天;在day-of-week字段用“1C”指在这周日或之后包括calendar的第一天。

不常用,可以不了解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天涯共明月

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值