quartz学习笔记之相关概念整理

quartz学习笔记之相关概念整理

Quartz三个核心概念

  • 调度器:Scheduler
  • 任务:Job
  • 触发器:Trigger

Quartz体系结构

  • JobDetail:包含任务的实现类以及类的信息;
  • Trigger:决定任务什么时候被调用;分为SimpleTrigger和CronTrigger(常用);
  • scheduler:定时、周期地执行JobDetail的信息
Quartz重要组成
  • Job: 接口,只有一个参数;
  • JobDetail:Job的实现类;
  • JobBuilder:创建JobDetail的实例;
  • JobStore:保存Job数据;(保存到内存中、数据库中);
  • Trigger:
  • TreadPool:
  • TriggerBuilder:
  • Scheduler:调度器;
  • Calender:一个Trigger可以和多个Calender关联,以排除或者包含某些时间点
  • 监听器:JobListener、TriggerListener、SchedulerListener;

代码示例(一)

package com.weyoung.platform.quartz.schedule;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * @Author Mr.wang
 * @Description
 * @Date 2019/6/2
 */
public class QuartzJobInit implements Job {

    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzJobInit.class);

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

        Date date = new Date();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = sf.format(date);
        run(format);
    }

    public void run(String format) {
        LOGGER.info("QuartzJobInit.execute.run:{}", format);
        System.out.println("QuartzJobInit.execute.run:{}" + format);
    }
}
package com.weyoung.platform.quartz.schedule;

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

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

/**
 * @功能描述:
 * @时间: 2019/6/22 23:43
 * @作者: wanglixia
 */
public class TestJob {
    public static void main(String[] args) {
        // 创建一个JobDetail实例,将该实例与QuartzJobInit的Class进行绑定
        JobDetail jobDetail = JobBuilder.newJob(QuartzJobInit.class).withIdentity("myJob", "group1").build();
        // 创建一个Trigger实例,用来触发Job去执行
        Trigger trigger = TriggerBuilder.newTrigger().withIdentity("myTrigger", "triggerGroup1")
                .startNow()
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();
        // 创建Scheduler实例,
        StdSchedulerFactory factory = new StdSchedulerFactory();
        Scheduler scheduler = null;
        try {
            scheduler = factory.getScheduler();
            scheduler.start();
            Date date = new Date();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format = sf.format(date);
            System.out.println("QuartzJobInit.main" + format);
//            LOGGER.info("QuartzJobInit.main", format);
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

Job 接口的实现

  • Job接口中只有一个execute方法,然后在其中写业务逻辑;
    • 生命周期:每次调度器Scheduler在执行job时,会在调用execute方法之前创建一个新的job实例;调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收。
  • JobDetail为Job实例提供了许多设置属性,以及JobDataMap成员变量属性,用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。重要属性如下:
    • name
    • group 任务所在组
    • jobClass 任务实现类
    • jobDataMap

JobExecutionContext

  • 当Scheduler调用一个Job时,就会将JobExecutionContext传递给Job的execute方法;
  • Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。

JobDataMap

  • 在进行任务调度时JobDataMap存储在JobExecutionContext中,非常方便获取;
  • JobDataMap可以用来装载任何可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它;
  • JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型。
JobDataMap获取方式:
从Map中直接获取;
  • 方式一:JobDataMap

添加数据:

// 创建一个JobDetail实例,将该实例与QuartzJobInit的Class进行绑定
JobDetail jobDetail = JobBuilder.newJob(QuartzJobInit.class)
        .withIdentity("myJob", "group1")
        // 传参
        .usingJobData("message", "hello myJob")
        .usingJobData("FloatJobValue", 3.14F)
        .build();
// 创建一个Trigger实例,用来触发Job去执行
Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("myTrigger", "triggerGroup1")
        .usingJobData("message", "hello myTrigger")
        .usingJobData("DoubleTriggerValue", 2.0D)
        .startNow()
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();

获取数据:

JobKey key = context.getJobDetail().getKey();
        System.out.println("key============>" + key.getName()+":" + key.getGroup());
        TriggerKey triggerKey = context.getTrigger().getKey();
        System.out.println("triggerKey============>" + triggerKey.getName()+":" + triggerKey.getGroup());
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        JobDataMap dataMap = context.getTrigger().getJobDataMap();

        String message = jobDataMap.getString("message");
        float floatJobValue = jobDataMap.getFloatValue("FloatJobValue");
        String triggerMsg = dataMap.getString("message");
        double doubleJobValue = dataMap.getDoubleValue("DoubleTriggerValue");
  • 方式二:getMergedJobDataMap
    • Trigger和JobDetail中有相同的key时,Trigger中的值就会覆盖掉JobDetail中的值。
    • Job实现类中添加setter方法对应JobDataMap的键值(Quartz框架默认的JobFactory实现类在初始化job实例对象时会自动调用这些setter方法)。
    • 直接定义属性,添加getter和setter方法即可;
JobDataMap mergedJobDataMap = context.getMergedJobDataMap();

触发器 Trigger

重要的两个实现类
  • CronTriggerImpl
    • 基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用;
    • CRON表达式:L可以和W一起使用;周字段的英文字母不区分大小写;
  • SimpleTriggerImpl
    • 在一个指定时间段内执行一次作业任务;或者在指定时间间隔内多次执行作业任务;
    • 重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值。
    • 重复时间间隔必须是0或者长整数;
    • 一旦制定了endAt,那么它就会覆盖重复次数参数的效果。endAt优先于withRepeatCount;
重要属性
  • JobKey:job实例的标识,触发器被触发时,该jobkey指定的实例会被触发执行;
  • StartTime:触发器首次被触发的时间;类型java.util.Date;
  • EndTime:触发器不再被触发的时间;类型java.util.Date;

调度器Scheduler

Scheduler-工厂模式
  • SchedulerFactory创建的;
    • StdSchedulerFactory;
      • 使用一组参数(java.util.Properties)来创建和初始化Quartz调度器;
      • 配置参数一般在quartz.properties中
      • 调用getScheduler方法就能创建和初始化调度器对象;
    • DirectSchedulerFactory;
主要函数
  • Date scheduleJob(JobDetail jobDetail, Trigger trigger);绑定jobDetail和trigger注册进scheduler中;返回最近一次即将执行的时间;
  • void start(); // 启动
  • void standby();// 挂起,挂起后可通过start恢复
  • void shutdown();// 关闭,不能恢复执行,强行恢复报出异常
    • shutdown(true)?/ 等待所有正在执行的job执行完毕之后,再关闭scheduler;
    • shutdown(false)?/ 表示直接关闭scheduler

quartz.properties

  • 文档的位置及加载顺序;优先读取工程中自定义的,没有的话去读quartz中的文件;
  • 组成部分
    • 调度器属性
      • org.quartz.scheduler.instanceName:用来区分特定的调度器实例,可以按照功能用途来给调度器起名;
      • org.quartz.scheduler.instanceId:和前者一样,也允许任何字符串,但这个值必须在所有调度器实例中是唯一的,尤其是在一个集群当中,作为集群的唯一key。如果想让Quartz生成这个值的话,可以设置为AUTO;
    • 线程池属性
      • threadCount:指定线程数,至少为1;
      • threadPriority:线程的优先级;
      • org.quartz.threadPool.class:线程池的实现类;
    • 作业存储设置
      • 描述了在调度器实例的生命周期中,Job和Trigger的信息是如何被存储的;
    • 插件配置
      • 满足特定需求用到的Quartz插件的配置。

详细配置如下:

# Default Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
# ===========================================================================
# Configure Main Scheduler Properties 调度器属性
# ===========================================================================
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.instanceid:AUTO
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
# ===========================================================================  
# Configure ThreadPool 线程池属性  
# ===========================================================================
#线程池的实现类(一般使用SimpleThreadPool即可满足几乎所有用户的需求)
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
#指定线程数,至少为1(无默认值)(一般设置为1-100直接的整数合适)
org.quartz.threadPool.threadCount: 10
#设置线程的优先级(最大为java.lang.Thread.MAX_PRIORITY 10,最小为Thread.MIN_PRIORITY 1,默认为5)
org.quartz.threadPool.threadPriority: 5
#设置SimpleThreadPool的一些属性
#设置是否为守护线程
#org.quartz.threadpool.makethreadsdaemons = false
#org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
#org.quartz.threadpool.threadsinheritgroupofinitializingthread=false
#线程前缀默认值是:[Scheduler Name]_Worker
#org.quartz.threadpool.threadnameprefix=swhJobThead;
# 配置全局监听(TriggerListener,JobListener) 则应用程序可以接收和执行 预定的事件通知
# ===========================================================================
# Configuring a Global TriggerListener 配置全局的Trigger监听器
# MyTriggerListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)
# ===========================================================================
#org.quartz.triggerListener.NAME.class = com.swh.MyTriggerListenerClass
#org.quartz.triggerListener.NAME.propName = propValue
#org.quartz.triggerListener.NAME.prop2Name = prop2Value
# ===========================================================================
# Configuring a Global JobListener 配置全局的Job监听器
# MyJobListenerClass 类必须有一个无参数的构造函数,和 属性的set方法,目前2.2.x只支持原始数据类型的值(包括字符串)
# ===========================================================================
#org.quartz.jobListener.NAME.class = com.swh.MyJobListenerClass
#org.quartz.jobListener.NAME.propName = propValue
#org.quartz.jobListener.NAME.prop2Name = prop2Value
# ===========================================================================  
# Configure JobStore 存储调度信息(工作,触发器和日历等)
# ===========================================================================
# 信息保存时间 默认值60秒
org.quartz.jobStore.misfireThreshold: 60000
#保存job和Trigger的状态信息到内存中的类
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
# ===========================================================================  
# Configure SchedulerPlugins 插件属性 配置
# ===========================================================================
# 自定义插件  
#org.quartz.plugin.NAME.class = com.swh.MyPluginClass
#org.quartz.plugin.NAME.propName = propValue
#org.quartz.plugin.NAME.prop2Name = prop2Value
#配置trigger执行历史日志(可以看到类的文档和参数列表)
org.quartz.plugin.triggHistory.class = org.quartz.plugins.history.LoggingTriggerHistoryPlugin  
org.quartz.plugin.triggHistory.triggerFiredMessage = Trigger {1}.{0} fired job {6}.{5} at: {4, date, HH:mm:ss MM/dd/yyyy}  
org.quartz.plugin.triggHistory.triggerCompleteMessage = Trigger {1}.{0} completed firing job {6}.{5} at {4, date, HH:mm:ss MM/dd/yyyy} with resulting trigger instruction code: {9}  
#配置job调度插件  quartz_jobs(jobs and triggers内容)的XML文档  
#加载 Job 和 Trigger 信息的类   (1.8之前用:org.quartz.plugins.xml.JobInitializationPlugin)
org.quartz.plugin.jobInitializer.class = org.quartz.plugins.xml.XMLSchedulingDataProcessorPlugin
#指定存放调度器(Job 和 Trigger)信息的xml文件,默认是classpath下quartz_jobs.xml
org.quartz.plugin.jobInitializer.fileNames = my_quartz_job2.xml  
#org.quartz.plugin.jobInitializer.overWriteExistingJobs = false  
org.quartz.plugin.jobInitializer.failOnFileNotFound = true  
#自动扫描任务单并发现改动的时间间隔,单位为秒
org.quartz.plugin.jobInitializer.scanInterval = 10
#覆盖任务调度器中同名的jobDetail,避免只修改了CronExpression所造成的不能重新生效情况
org.quartz.plugin.jobInitializer.wrapInUserTransaction = false
# ===========================================================================  
# Sample configuration of ShutdownHookPlugin  ShutdownHookPlugin插件的配置样例
# ===========================================================================
#org.quartz.plugin.shutdownhook.class = \org.quartz.plugins.management.ShutdownHookPlugin
#org.quartz.plugin.shutdownhook.cleanShutdown = true
#
# Configure RMI Settings 远程服务调用配置
#
#如果你想quartz-scheduler出口本身通过RMI作为服务器,然后设置“出口”标志true(默认值为false)。
#org.quartz.scheduler.rmi.export = false
#主机上rmi注册表(默认值localhost)
#org.quartz.scheduler.rmi.registryhost = localhost
#注册监听端口号(默认值1099)
#org.quartz.scheduler.rmi.registryport = 1099
#创建rmi注册,false/never:如果你已经有一个在运行或不想进行创建注册
# true/as_needed:第一次尝试使用现有的注册,然后再回来进行创建
# always:先进行创建一个注册,然后再使用回来使用注册
#org.quartz.scheduler.rmi.createregistry = never
#Quartz Scheduler服务端端口,默认是随机分配RMI注册表
#org.quartz.scheduler.rmi.serverport = 1098
#true:链接远程服务调度(客户端),这个也要指定registryhost和registryport,默认为false
# 如果export和proxy同时指定为true,则export的设置将被忽略
#org.quartz.scheduler.rmi.proxy = false

基于Maven的SpringMvc工程整合Quartz

使用Quartz配置作业
  • MethodInvokingJobDetailFactoryBean;
  • JobDetailFactoryBean:比较灵活,支持给作业传递数据;

Quartz相关文档

相关链接

本文整理自:慕课网教程
Java定时任务调度工具详解之Quartz篇:https://www.imooc.com/learn/846

分享

欢迎扫描下方二维码,关注weyoung公众号,一起交流学习~~

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值