quartz

简介

  • quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,是完全由java开发的一个开源的任务日程管理系统,“任务进度管理器”就是一个在预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。

  • quartz是一个功能丰富的开源的任务调用系统,它可以创建简单或者复杂的几十、几百、甚至成千上万的job。此外,quartz调度器还支持JTA事务和集群。

maven引入

<dependency><groupId>org.quartz-scheduler</groupId><artifactId>quartz</artifactId><version>2.3.2</version>
</dependency>

quartz三要素

  • Scheduler:任务调度器,所有的任务都是从这里开始。
  • Trigger:触发器,定义任务执行的方式、间隔。
  • JobDetail & Job : 定义任务具体执行的逻辑。

Scheduler

  • 调度器
  • 使用工厂模式创建。
  • scheduler 是quartz的核心所在,所有的任务都是通过scheduler开始。
  • scheduler是一个接口类,所有的具体实现类都是通过SchedulerFactory工厂类实现,但是SchedulerFactory有两个具体的实现类:DirectSchedulerFactory和StdSchedulerFactory。

StdSchedulerFactory:默认值加载是当前工作目录下的quartz.properties属性文件。如果加载失败,会去加载org/quartz包下的quartz.properties属性文件。一般使用这个实现类就能满足我们的要求。
查看StdSchedulerFactory.getDefaultScheduler(),会发现用的是new StdSchedulerFactory(),在initialize()方法可以看到默认从指定配置的文件或quartz.properties读取配置。

  • 调度器待机状态、关闭状态

在调用scheduler.start()启动调度器后,可以使用scheduler.standby();将调度器转为待机状态,此状态下任务和触发器不会被触发。
另外,可以使用scheduler.shutdown()关闭调度器,是不可逆的,即调用后是不可以重新开始的。
它的参数不同,意义有所不同:

//方法会马上返回,正在执行的任务会继续执行
scheduler.shutdown(false);
//默认是false
scheduler.shutdown()//知道正在执行的任务执行完成才返回
scheduler.shutdown(true);

Trigger

  • 触发器
  • 使用builder模式创建。
  • Quartz中最常用的两类:SimpleTrigger和CronTrigger。

1、SimpleTrigger:用来触发只需执行一次或者在给定时间触发并且重复N次且每次执行延迟一定时间的任务。
2、CronTrigger:按照日历触发,使用cron表达式,更加灵活的设置时间。

JobDetail & Job

  • 任务
  • 使用builder模式创建。
  • 每个任务实现Job接口,重写里面的execute方法。
  • JobDetail是Job的细节,许多任务的信息都可通过JobDetail设置和获取。

简单实例1

  • HelloJob1实现Job任务,通过jec获取任务的一些属性。
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import com.sping.boot.util.DateUtils;public class HelloJob1 implements Job{@Overridepublic void execute(JobExecutionContext jec) throws JobExecutionException {DateUtils.printCurrentTime();System.out.println("HelloScheduler !!!");JobDataMap jdm = jec.getJobDetail().getJobDataMap();System.out.println("jdm key1: "+ jdm.getString("key1"));System.out.println("jdm key2: "+ jdm.getInt("key2"));System.out.println("jdm key3: "+ jdm.getDouble("key3"));jdm = jec.getTrigger().getJobDataMap();System.out.println("jdm key1: "+ jdm.getString("key1"));System.out.println("jdm key2: "+ jdm.getInt("key2"));//getMergedJobDataMap方法获取的是两个合并的map,当key相同时,trigger的属性会覆盖jobDetail的属性jdm = jec.getMergedJobDataMap();System.out.println("jdm key1: "+ jdm.getString("key1"));System.out.println("jdm key2: "+ jdm.getInt("key2"));System.out.println("jdm key3: "+ jdm.getDouble("key3"));Trigger trigger = jec.getTrigger();Date startDate = trigger.getStartTime();Date endDate = trigger.getEndTime();System.out.print("startDate: ");DateUtils.printTime(startDate);System.out.print("endDate: ");DateUtils.printTime(endDate);}
}
  • HelloScheduler1,JobDetail里设置一些任务的其他信息;使用SimpleTrigger来定义触发时间。
import java.util.Date;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import com.sping.boot.util.DateUtils;public class HelloScheduler1 {public static void main(String[] args) throws SchedulerException {DateUtils.printCurrentTime();//开始时间Date startDate = DateUtils.getTimeAddSeconds(2);//结束时间Date endDate = DateUtils.getTimeAddSeconds(6);//创建JobJobDetail jobDetail = JobBuilder.newJob(HelloJob1.class).withIdentity("myjob", "job_group_one").usingJobData("key1", "value1").usingJobData("key2", 2).usingJobData("key3", 3.0).build();System.out.println("name: "+ jobDetail.getKey().getName());System.out.println("group: "+ jobDetail.getKey().getGroup());System.out.println("jobClass: "+ jobDetail.getJobClass().getName());//创建triggerTrigger trigger = TriggerBuilder.newTrigger().withIdentity("mytrigger", "trigger_group_one").usingJobData("key1", "value44").usingJobData("key2", 55)//.startNow().startAt(startDate).endAt(endDate).withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(2).repeatForever()).build();//创建scheduleSchedulerFactory sef = new StdSchedulerFactory();Scheduler sd = sef.getScheduler();sd.start();sd.scheduleJob(jobDetail, trigger);}
}
  • 其它自定义类
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;public class DateUtils {private DateUtils() {}public static void printCurrentTime() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(new Date()));}public static void printTime(Date date) {if(date == null) {return;}SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sdf.format(date));}public static Date getTimeAddSeconds(int seconds) {Calendar c = Calendar.getInstance();return new Date(c.getTimeInMillis() + seconds * 1000);}
}

简单实例2

  • HelloJob2实现Job任务,通过定义成员变量的方法来获取属性。
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.Trigger;
import com.sping.boot.util.DateUtils;public class HelloJob2 implements Job{private String key1;private int key2;private double key3;public String getKey1() {return key1;}public void setKey1(String key1) {this.key1 = key1;}public int getKey2() {return key2;}public void setKey2(int key2) {this.key2 = key2;}public double getKey3() {return key3;}public void setKey3(double key3) {this.key3 = key3;}@Overridepublic void execute(JobExecutionContext jec) throws JobExecutionException {DateUtils.printCurrentTime();System.out.println("HelloScheduler !!!");//通过定义成员变量的方法来获取属性System.out.println("jdm key1: "+ key1);System.out.println("jdm key2: "+ key2);System.out.println("jdm key3: "+ key3);Trigger trigger = jec.getTrigger();Date startDate = trigger.getStartTime();Date endDate = trigger.getEndTime();System.out.print("startDate: ");DateUtils.printTime(startDate);System.out.print("endDate: ");DateUtils.printTime(endDate);}
}
  • HelloScheduler2,JobDetail里设置一些任务的其他信息;使用CronTrigger来定义触发时间。
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import com.sping.boot.util.DateUtils;public class HelloScheduler2 {public static void main(String[] args) throws SchedulerException {DateUtils.printCurrentTime();//创建JobJobDetail jobDetail = JobBuilder.newJob(HelloJob2.class).withIdentity("myjob", "job_group_one").usingJobData("key1", "value1").usingJobData("key2", 2).usingJobData("key3", 3.0).build();System.out.println("name: "+ jobDetail.getKey().getName());System.out.println("group: "+ jobDetail.getKey().getGroup());System.out.println("jobClass: "+ jobDetail.getJobClass().getName());//创建triggerCronTrigger cronTrigger = (CronTrigger) TriggerBuilder.newTrigger().withIdentity("crontrigger")//使用灵活的cron表达式(时 分 秒 日 周 月 年).withSchedule(CronScheduleBuilder.cronSchedule("* * * * * ? *")).build();//创建scheduleSchedulerFactory sef = new StdSchedulerFactory();Scheduler sd = sef.getScheduler();sd.start();sd.scheduleJob(jobDetail, cronTrigger);}
}

quartz.properties的一些配置说明

此文件在quartz的jar包有,可直接拿过来使用不过只有基本的几个配置 自己可根据需要进行扩充;另外如果项目中没有对该配置文件重写,则quartz会加载自己jar包中的quartz.properties文件。

# 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

扩展

  • springboot集成quartz

maven仅需引入

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
  • 简单实例
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;/*** @description 自定义任务类,通过注解实现*/
@Component
public class HelloJob3 implements Job {@Overridepublic void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {JobDataMap jdm = jobExecutionContext.getJobDetail().getJobDataMap();String name = jdm.getString("name");System.out.println("name: " + name);}
}
import org.quartz.JobDataMap;
import org.quartz.Trigger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.*;/*** @description 配置Quartz的Scheduler调度器*/
@Configuration
public class QuartzJobConfigure {/*** @description 使用JobDetailFactoryBean进行配置,自定义任务需要实现Job接口* @param helloJob* @return*/@Bean("jobDetail")public JobDetailFactoryBean jobDetailFactoryBean(HelloJob3 helloJob) {JobDetailFactoryBean jobDetailFactoryBean = new JobDetailFactoryBean();jobDetailFactoryBean.setJobClass(helloJob.getClass());jobDetailFactoryBean.setDurability(true);//设置任务其他信息JobDataMap jobDataMap = new JobDataMap();jobDataMap.put("name", "Quartz");jobDetailFactoryBean.setJobDataMap(jobDataMap);return jobDetailFactoryBean;}/*** @description 普通的触发器,此处也可用Cron储发器实现* @param jobDetail* @return*/@Bean("simpleTrigger")public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetail) {SimpleTriggerFactoryBean simpleTriggerFactoryBean = new SimpleTriggerFactoryBean();simpleTriggerFactoryBean.setJobDetail(jobDetail.getObject());simpleTriggerFactoryBean.setStartDelay(5000);simpleTriggerFactoryBean.setRepeatInterval(2000);return simpleTriggerFactoryBean;}/*** @description 配置调度容器* @param simpleTrigger* @return*/@Bean(name = "scheduler")public SchedulerFactoryBean schedulerFactoryBean(Trigger simpleTrigger) {SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();//用于Quartz集群,QuartzScheduler启动时会更新已存在的JobschedulerFactoryBean.setOverwriteExistingJobs(true);//延时启动,应用启动1秒后schedulerFactoryBean.setStartupDelay(1);//注册触发器schedulerFactoryBean.setTriggers(simpleTrigger);return schedulerFactoryBean;}}

org.quartz相关推荐

  1. SpringBoot中实现quartz定时任务

    Quartz整合到SpringBoot(持久化到数据库) 背景 最近完成了一个小的后台管理系统的权限部分,想着要扩充点东西,并且刚好就完成了一个自动疫情填报系统,但是使用的定时任务是静态的,非常不利于 ...

  2. Java基于Quartz的定时任务调度服务(一)

    Quartz的基本用法 一 Quartz的简单介绍 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现,一个优秀的开源调度框架,其特点是:强大的 ...

  3. springboot整合Quartz实现动态配置定时任务

    版权声明:本文为博主原创文章,转载请注明出处. https://blog.csdn.net/liuchuanhong1/article/details/60873295 前言 在我们日常的开发中,很多 ...

  4. Quartz 2D Programming Guide笔记

    ###Graphics Contexts图形上下文### 图形上下文(graphics context)是绘制目标,可以理解为画布,包含着绘图时的参数和设备信息.类型为CGContextRef.获取g ...

  5. 【Quartz】实现接口封装化(二)

    原文:[Quartz]实现接口封装化(二)   前言   通过昨天的努力终于算是了解Quartz这个定时器的简单使用,为了更深一步的了解和基于以后希望在项目中能使用他.所有我对他做了一下简单的封装操作 ...

  6. quartz在集群环境下的最终解决方案

    在集群环境下,大家会碰到一直困扰的问题,即多个 APP 下如何用 quartz 协调处理自动化 JOB . 大家想象一下,现在有 A , B , C3 台机器同时作为集群服务器对外统一提供 SERVI ...

  7. 将Quartz.NET集成到 Castle中

    Castle是针对.NET平台的一个开源项目,从数据访问框架ORM到IOC容器,再到WEB层的MVC框架.AOP,基本包括了整个开发过程中的所有东西,为我们快速的构建企业级的应用程序提供了很好的服务. ...

  8. 初识Quartz(三)

    为什么80%的码农都做不了架构师?>>>    简单作业: package quartz_project.example3;import java.util.Date;import ...

  9. java timer cron_Java之旅--定时任务(Timer、Quartz、Spring、LinuxCron)

    在Java中,实现定时任务有多种方式.本文介绍4种.Timer和TimerTask.Spring.QuartZ.Linux Cron. 以上4种实现定时任务的方式.Timer是最简单的.不须要不论什么 ...

  10. Quartz动态添加、修改和删除定时任务

    2019独角兽企业重金招聘Python工程师标准>>> Quartz动态添加.修改和删除定时任务 转载于:https://my.oschina.net/haokevin/blog/1 ...

最新文章

  1. MVC之Model转Json
  2. NDK 编译和使用静态库、动态库
  3. uwsgi 的app变量名称必须为application
  4. java小基础之instanceof运算符
  5. Oracle的安装、配置与工具使用 实验笔记一
  6. 选择排序算法-C程序设计
  7. Bailian3142 球弹跳高度的计算【水题】
  8. 自己实现一个简易web服务器
  9. testbench实例 vhdl_VHDL的testbench的编写(转)
  10. linux自动ping脚本,linux 自动ping ip的shell脚本
  11. 浮栅场效应管 符号_华成英 - 模拟电子技术基础 | 场效应管
  12. linux源码解读系列
  13. python数字雨_用Python实现黑客帝国代码雨效果(3种方式)
  14. (九)青龙Tools 正式版/前端网页提交+后台管理/适用于所有场景/开饭开饭开饭 【2022年6月15日】【更新】
  15. keras的seq2seq
  16. duet连win10_duet display windows
  17. angularjs学习总结 详细教程(转载)
  18. 从Excel到Smartbi,国内头部企业的报表是这样进阶的!
  19. JWT生成token与中间件验证
  20. matlab dpm目标检测,车辆目标检测

热门文章

  1. 【计算机基础】repo学习笔记
  2. 新西兰android时区代码,Android北京时间转换为新西兰时间
  3. 【模拟】寄居蟹与海葵
  4. elementui 复制功能,无需下载插件纯原生实现
  5. flush privileges作用
  6. 史上最详细浏览器端网页截图方案分析
  7. 学生成绩管理系统-设计文档
  8. 再谈PINGPONG测试
  9. SeniorUI0302_Paint基本使用二(文字相关api)
  10. 记录一次oracle中count特别慢的解决方案