博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HelloQuartz
阅读量:3915 次
发布时间:2019-05-23

本文共 14147 字,大约阅读时间需要 47 分钟。

Quartz第一天内容

Quartz官方网站:http://www.quartz-scheduler.org

什么是Quartz?

- Quartz是一个功能非常强大的开源的作业调度框架;- 几乎可以集成任何java应用,小到单体应用,达到大型电子商务系统;- 可以用来执行成千上万的简单或者复杂的调度任务;- Quartz的任务被定义为一组标准的java组件,几乎可以执行任何编程任务;- Quartz包含了一些企业级功能:包括对JTA事务支持和集群功能;

Quartz能做什么?

定时发送邮件、短信通知;数据同步;

Quartz特点

强大的调度功能;灵活的使用方式;表达式 秒  分  时  天  月  周       0  0  8   ?   5  SUN#3集群功能;

Quartz的重要API

Job接口:任务;定义的任务要实现Job接口;JobDetail:对任务的描述;Trigger:触发器,可以定义任务执行时机、执行规则 - SimpleTrigger - CronTriggerScheduler:任务容器,调度器,使用触发器定义的规则去调度任务;JobStore:内存、JDBC;

第一个Quartz程序:每隔5秒钟打印一次Hello Quartz!

引入Quartz依赖
org.quartz-scheduler
quartz
2.3.0
首先编写任务:HelloQuartz implements JobHelloQuartzMain - 创建JobDetail - 创建Trigger - 创建Scheduler - 启动调度

在这里插入图片描述

package com.etoak.quartz01;import org.quartz.Job;import org.quartz.JobExecutionContext;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;public class HelloQuartzJob implements Job {    public HelloQuartzJob() {        System.out.println("创建HelloQuartzJob对象");    }    @Override    public void execute(JobExecutionContext context) {        LocalDateTime dateTime = LocalDateTime.now();        String date = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss SSS"));        System.out.println(date + "-Hello Quartz!");    }}
package com.etoak.quartz01;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class HelloQuartzMain {    public static void main(String[] args) throws SchedulerException {        // 1.创建JobDetail,使用建造者模式        JobDetail jobDetail = JobBuilder.newJob(HelloQuartzJob.class)                .withIdentity("hello", "hello")                .build();        // 2.创建Trigger        SimpleTrigger trigger = TriggerBuilder.newTrigger()                .withIdentity("hello", "hello")                .withSchedule(SimpleScheduleBuilder                        .simpleSchedule()                        .withIntervalInSeconds(5) // 每5秒钟执行一次                        .repeatForever()                ).build();        // 3.创建Scheduler        Scheduler scheduler = StdSchedulerFactory                .getDefaultScheduler();        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}

在这里插入图片描述

JobDetail和Trigger如何给Job任务传参、讲解SimpleTrigger

1. 任务两秒后执行、之后每隔三秒执行一次;
JobDetail给Job任务传参usingJobData();
package com.etoak.quartz02;import org.quartz.*;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;public class JobDetailParamJob implements Job {    private Integer id;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        JobDetail jobDetail = context.getJobDetail();        JobDataMap dataMap = jobDetail.getJobDataMap();        String first = dataMap.getString("first");        String date = LocalDateTime.now()                .format(DateTimeFormatter                        .ofPattern("yyyy-MM-dd HH:mm:ss"));        System.out.println(date + "-first:" + first);        System.out.println(date + "-second:" + id);        boolean third = dataMap.getBoolean("third");        System.out.println(date + "-third:" + third);    }}
package com.etoak.quartz02;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import java.text.SimpleDateFormat;import java.util.Date;// 任务两秒后执行、之后每隔三秒执行一次;// JobDetail给Job任务传参public class JobDetailParamMain {    public static void main(String[] args) throws SchedulerException {        JobDataMap dataMap = new JobDataMap();        dataMap.put("third", true);        JobDetail jobDetail = JobBuilder.newJob(JobDetailParamJob.class)            .withIdentity("param")            .usingJobData("first", "第一种传参")            .usingJobData("id", 100)            .usingJobData(dataMap)            .build();        // 创建Trigger        Date current = new Date();        System.out.println( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(current));        // 获得两秒后时间        Date twoSecondsAfter = new Date(current.getTime() + 2000L);        SimpleTrigger trigger = TriggerBuilder.newTrigger()            .withIdentity("param")            .startAt(twoSecondsAfter) //两秒后开始执行            .withSchedule(SimpleScheduleBuilder                    .simpleSchedule()                    .withIntervalInSeconds(3) //之后每隔3秒执行一次                    .repeatForever()            ).build();        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}

在这里插入图片描述

2. 任务两秒后执行,之后每隔三秒一次,15秒后停止执行;
Trigger给Job任务传参usingJobData()
package com.etoak.quartz03;import org.quartz.*;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;public class TriggerParamJob implements Job {    private Integer second;    public Integer getSecond() {        return second;    }    public void setSecond(Integer second) {        this.second = second;    }    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        Trigger trigger = context.getTrigger();        JobDataMap dataMap = trigger.getJobDataMap();        String first = dataMap.getString("first");        boolean third = dataMap.getBoolean("third");        String date = LocalDateTime.now()                .format(DateTimeFormatter                        .ofPattern("yyyy-MM-dd HH:mm:ss"));        System.out.println(date + "-first:" + first);        System.out.println(date + "-second:" + second);        System.out.println(date + "-third:" + third);    }}

这里时间用的是LocalDateTime,传参的时候转了格式

package com.etoak.quartz03;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import java.time.LocalDateTime;import java.time.ZoneId;import java.util.Date;public class TriggerParamJobMain {    public static void main(String[] args) throws SchedulerException {        JobDetail jobDetail = JobBuilder.newJob(TriggerParamJob.class)                .withIdentity("param", "param")                .build();        LocalDateTime now = LocalDateTime.now();        System.out.println("当前时间:" + now);        LocalDateTime twoSecondsAfter = now.plusSeconds(2);        LocalDateTime fifteenSecondsAfter = now.plusSeconds(15);        Date two = Date.from(twoSecondsAfter.atZone(ZoneId.systemDefault()).toInstant());        Date fifteen = Date.from(fifteenSecondsAfter.atZone(ZoneId.systemDefault()).toInstant());        JobDataMap dataMap = new JobDataMap();        dataMap.put("third", false);        SimpleTrigger trigger = TriggerBuilder.newTrigger()                .withIdentity("param")                .startAt(two)                .endAt(fifteen)                .usingJobData("first", "第一种方式")                .usingJobData("second", 2)                .usingJobData(dataMap)                .withSchedule(SimpleScheduleBuilder.simpleSchedule()                        .withIntervalInSeconds(3)                        .repeatForever()                ).build();        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}

在这里插入图片描述

3. 任务两秒后执行,之后每隔三秒执行一次,执行2次;
合并JobDetail和Trigger的参数
package com.etoak.quartz04;import org.quartz.Job;import org.quartz.JobDataMap;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.time.LocalDateTime;import java.time.format.DateTimeFormatter;import java.util.Map;import java.util.Set;public class MergeParamJob implements Job {    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        JobDataMap dataMap = context.getMergedJobDataMap();        String date = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));        Set
> entrySet = dataMap.entrySet(); for (Map.Entry
entry : entrySet) { String key = entry.getKey(); Object value = entry.getValue(); System.out.println(date + "-" + key + ':' + value); } }}
package com.etoak.quartz04;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;import java.text.SimpleDateFormat;import java.util.Date;public class MegerParamMain {    public static void main(String[] args) throws SchedulerException {        Date current = new Date();        System.out.println( new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(current));        // 获得两秒后时间        Date twoSecondsAfter = new Date(current.getTime() + 2000L);        SimpleTrigger trigger = TriggerBuilder.newTrigger()                .usingJobData("third", 3)                .usingJobData("second", "trigger")                .startAt(twoSecondsAfter)                .withSchedule(SimpleScheduleBuilder                        .simpleSchedule().withIntervalInSeconds(3)                        .withRepeatCount(2)                ).build();        JobDetail jobDetail = JobBuilder.newJob(MergeParamJob.class)                .usingJobData("first", "first")                .usingJobData("second", "JobDetail")                .build();        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}

上面的两次指的是第一次执行之后再执行两次。

Cron表达式

Cron-Expressions用于配置CronTrigger的实例。Cron Expressions是由七个子表达式组成的字符串,用于描述时间的各个细节。这些子表达式用空格分隔,并表示:[秒]     [分]     [小时]   [天]         [月]    [周]        [年]Seconds  Minutes  Hours  Day-of-Month  Month  Day-of-Week  Year (optional field)时间字段	  是否必填	允许值	         特殊字符 秒	        是	     0-59             ,-*/  分	        是	     0-59             ,-*/ 时	        是	     0-23             ,-*/ 日	        是	     1-31             , - * ? / L W C 月	        是    1-12或者JAN-DEC     ,-*/ 周	        是    1-7或者SUN-SAT      ,-* ? / L C #      说明:周天用1表示,依次类推 年	        否    空或1970-2099        ,-*/ ,:表示或的关系 -:范围的关系【比如1-21】 *:每秒、每分、每小时等  /:每天哪个时间执行 L:用于每月,或每周,表示为每月的最后一天,或每个月的最后星期几如“6L”表示“每月的最后一个星期五” W:该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。  例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;  如果15号是星期二,那结果就是15号星期二。  但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。 W字符串只能指定单一日期,而不能指定日期范围; #:是用来指定“的”每月第n个工作日,例在每周(day-of-week)这个字段中内容为"6#3" or "FRI#3" 则表示“每月第三个星期五” 表达式举例   每天14:20提醒打卡:0 20 14 ? * MON-FRI   每天1点到1点59分,每隔5分执行:0 0/5 1 * * ?   周一到周五9:00上班的时候执行:0 0 9 ? * 2-6 注意点:?只能用在"天和周"        如果有一个字段是*,那么另外一个用?;        天和周有一个确定了,另外一个就得用?;
package com.etoak.quartz05;import org.quartz.Job;import org.quartz.JobExecutionContext;import org.quartz.JobExecutionException;import java.text.SimpleDateFormat;import java.util.Date;public class CronJob implements Job {    @Override    public void execute(JobExecutionContext context) throws JobExecutionException {        System.out.println(        new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")                .format(new Date()) + "-Hello Quartz"        );    }}
package com.etoak.quartz05;import org.quartz.*;import org.quartz.impl.StdSchedulerFactory;public class CronJobMain {    public static void main(String[] args) throws SchedulerException {        // JobDetail        JobDetail jobDetail = JobBuilder.newJob(CronJob.class)                .withIdentity("cron", "cron")                .build();        // Trigger        CronTrigger trigger = TriggerBuilder                .newTrigger()                .withSchedule(CronScheduleBuilder                        .cronSchedule("0/5 * * * * ?")                ).build();        // Scheduler        Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();        scheduler.scheduleJob(jobDetail, trigger);        scheduler.start();    }}

整合Spring

maven依赖

org.quartz-scheduler:quartz:2.3.0org.springframework:spring-jdbc:5.0.7.RELEASEorg.springframework:spring-tx:5.0.7.RELEASEorg.springframework:spring-context-support:5.0.7.RELEASE

配置ioc容器中的bean

MethodInvokingJobDetailFactoryBean  特点:不要求任务类实现任何接口  属性:name、group、targetObject(job bean)、targetMethod(方法名)CronTriggerFactoryBean  属性:name、group、jobDetail、cronExpressionSchedulerFactoryBean  属性:triggers --> list

Quartz集群

1. 创建数据库和表

创建一个名称为quartz的数据库(字符集编码:utf8)创建表:执行tables_mysql_innodb.sql

2. 创建项目,添加maven依赖

org.quartz-scheduler:quartz:2.3.0org.springframework:spring-jdbc:5.0.7.RELEASEorg.springframework:spring-tx:5.0.7.RELEASEorg.springframework:spring-context-support:5.0.7.RELEASEmysql:mysql-connector-java:5.1.34

3. 将quartz.properties文件放在src/main/resources下

在配置SchedulerFactoryBean的时候,有个configLocation属性,指定quartz.properties文件的位置;#可以设置为任意,用在 JDBC JobStore中来唯一标识实例,但是所有集群节点中必须相同。org.quartz.scheduler.instanceName=SpringClusterTest# 属性为 AUTO即可,基于主机名和时间戳来产生实例 ID org.quartz.scheduler.instanceId = AUTO ## 线程org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPoolorg.quartz.threadPool.threadCount = 10org.quartz.threadPool.threadPriority = 5org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread = true## 存储org.quartz.jobStore.misfireThreshold = 60000#JobStoreTX,将任务持久化到数据库中。因为集群中节点依赖于数据库来传播 Scheduler实例的状态,你只能在使用 JDBC JobStore 时应用 Quartz 集群。这意味着你必须使用 JobStoreTX 或是 JobStoreCMT 作为 Job 存储,不能在集群中使用 RAMJobStore。org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTXorg.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegateorg.quartz.jobStore.tablePrefix = QRTZ_org.quartz.jobStore.maxMisfiresToHandleAtATime=10#值 true,表示 Scheduler实例要参与到一个集群当中。这一属性会贯穿于调度框架的始终,用于修改集群环境中操作的默认行为。org.quartz.jobStore.isClustered = true #定义了Scheduler 实例检入到数据库中的频率(单位:毫秒)。Scheduler 检查是否其他的实例到了它们应当检入的时候未检入;这能指出一个失败的 Scheduler 实例,且当前 Scheduler 会以此来接管任何执行失败并可恢复的 Job。通过检入操作,Scheduler 也会更新自身的状态记录。clusterChedkinInterval 越小,Scheduler 节点检查失败的 Scheduler 实例就越频繁。默认值是 15000 (即15 秒)。org.quartz.jobStore.clusterCheckinInterval = 5000

4. 配置spring容器

DataSource(HikariDataDource)  属性:driverClassName、jdbcUrl、username、passwordDataSourceTransactionManager  属性:dataSourceJobDetailFactoryBean  属性:name、group、jobClass、durability(持久化任务)  特点:要求任务继承QuartzJobBean类CronTriggerFactoryBean  属性:name、group、jobDetail、cronExpressionSchedulerFactoryBean  属性:triggers、configLocation、dataSource、transactionManager、applicationContextSchedulerContextKey(spring ioc)

转载地址:http://ixvrn.baihongyu.com/

你可能感兴趣的文章
Xamarin.Forms弹出对话框插件
查看>>
UnitTest in .NET(Part 4)
查看>>
大量SQL的解决方案——sdmap
查看>>
与其每天重复,不如试着构建「正反馈闭环」
查看>>
【Azure学习.01】先从账号注册开始
查看>>
如何运用领域驱动设计 - 工作单元
查看>>
服务器应用服务为何卡顿?原来是内存耗尽惹的祸!
查看>>
什么?原来C#还有这两个关键字
查看>>
Mbp,一个用于学习.net core的开发框架
查看>>
【Magicodes.IE 2.0.0-beta1版本发布】已支持数据表格、列筛选器和Sheet拆分
查看>>
net下的高性能轻量化半自动orm+linq的《SqlBatis》
查看>>
如何利用Serilog的RequestLogging来精简ASP.NET Core的日志输出
查看>>
在 Blazor WebAssembly 中使用 gRPC-Web
查看>>
【实战 Ids4】║ 在Swagger中调试认证授权中心
查看>>
.NET Core开发实战(第10课:环境变量配置提供程序)--学习笔记
查看>>
WTM系列视频教程:View和Taghelper
查看>>
面试官:你连HTTP请求Post和Get都不了解?
查看>>
.NET Core 3.0 即将结束生命周期,建议迁移 3.1
查看>>
开源、免费、企业级的SiteServer CMS .NET CORE 7.0 预览版发布
查看>>
基于.NET下的人工智能|利用ICSharpCore搭建基于.NET Core的机器学习和深度学习的本地开发环境...
查看>>