Quartz/Spring整合quartz
来自 https://segmentfault.com/a/1190000009972187
第一章:课程介绍
1-1 初识Quartz
Quartz概要
OpenSymphony提供的强大的开源任务调度框架
官网:http://www.quartz-scheduler.org
纯Java实现,精细控制排程
Quartz特点
强大的调度功能
灵活的应用方式
分布式和集群能力
Quartz的设计模式
Builder模式
Factory模式
组件模式
链式写法
Quartz三个核心概念
调度器:将任务和触发器一一对应
任务:需要做什么,值Service
触发器:定义时间
Quartz体系结构
JobDetail
trigger
SimpleTrigger
CronTrigger
scheduler
start
stop
pause
resume
示意图
Quartz重要组成
Job
JobDetail
JobBuilder
JobStore
Trigger
TriggerBuilder
ThreadPool
Scheduler
Calendar:一个Trigger可以和多个Calendar关联,以排除或包含某些时间点
监听器
JobListener
TriggerListener
SchedulerListener
第二章:Quartz详解
2-1 第一个Quartz程序
准备工作
建立Maven项目工程
引入Quartz包
编写第一个Quartz任务
让任务每隔两秒打印一次hellworld
代码演示
1.编写任务类
package com.myimooc.helloquartz.one; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * 编写 自定义任务 * @author ZhangCheng on 2017-06-26 * */ public class HelloJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Exec Time Is : " + sf.format(date)); // 编写具体的业务逻辑 System.out.println("Hello World!"); } }
2.编写任务调度类
package com.myimooc.helloquartz.one; import java.text.SimpleDateFormat; 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; /** * 编写 任务调度类 * @author ZhangCheng on 2017-06-26 * */ public class HelloScheduler { public static void main(String[] args) throws SchedulerException { // 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定 JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class) .withIdentity("myjob", "jobgroup1")// 定义标识符 .build(); System.out.println("jobDetail's name : " + jobDeatil.getKey().getName()); System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup()); System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName()); // 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger","trigroup1")// 定义标识符 .startNow()// 定义立即执行 .withSchedule(SimpleScheduleBuilder .simpleSchedule() .withIntervalInSeconds(2) .repeatForever())// 定义执行频度 .build(); // 创建 Scheduler 实例 SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler(); // 绑定 JobDetail 和 trigger scheduler.scheduleJob(jobDeatil, trigger); // 执行任务 scheduler.start(); // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Time Is : " + sf.format(date)); } }
2-2 浅谈Job&JobDetail
Job定义
实现业务逻辑的任务接口
浅谈Job
Job接口非常容易实现,只有一个execute方法,类似TimerTask的run方法,在里面编写业务逻辑
Job接口源码
public interface Job { void execute(JobExecutionContext context) throws JobExecutionException; }
Job实例在Quartz中的生命周期
每次调度器执行job时,它在调用execute方法前会创建一个新的job实例
当调用完成后,关联的job对象实例会被释放,释放的实例会被垃圾回收机制回收
浅谈JobDetail
JobDetail为Job实例提供了许多设置属性,以及JobDetailMap成员变量属性,它用来存储特定Job实例的状态信息,调度器需要借助JobDetail对象来添加Job实例。
JobDetail属性
name:任务名称
group:任务所属组
jobClass:任务实现类
jobDataMap:传参的作用
2-3 浅谈JobExecutionContext&JobDataMap(上)
JobExecutionContext是什么
当Scheduler调用一个Job,就会将JobExecutionContext传递给Job的execute()方法;
Job能通过JobExecutionContext对象访问到Quartz运行时候的环境以及Job本身的明细数据。
JobDataMap是什么
在进行任务调度时JobDataMap存储在JobExecutionContext中,非常方便获取
JobDataMap可以用来装载任务可序列化的数据对象,当job实例对象被执行时这些参数对象会传递给它
JobDataMap实现了JDK的Map接口,并且添加了一些非常方便的方法用来存取基本数据类型
2-4 浅谈JobExecutionContext&JobDataMap(下)
获取JobDataMap的两种方式
从Map中直接获取
Job实现类中添加setter方法对应JobDataMap的键值
(Quartz框架默认的JobFactory实现类在初始化job实例对象时会自动地调用这些setter方式)
代码演示
1.HelloScheduler类改造
package com.myimooc.helloquartz.two; import java.text.SimpleDateFormat; 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; /** * 编写 任务调度类 * @author ZhangCheng on 2017-06-26 * */ public class HelloScheduler { public static void main(String[] args) throws SchedulerException { // 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定 JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class) .withIdentity("myjob", "jobgroup1")// 定义标识符 .usingJobData("message", "hello myjob1")// 传入自定义参数 .usingJobData("floatJobValue", 3.14F)// 传入自定义参数 .build(); System.out.println("jobDetail's name : " + jobDeatil.getKey().getName()); System.out.println("jobDetail's group : " + jobDeatil.getKey().getGroup()); System.out.println("jobDetail's jobClass : " + jobDeatil.getJobClass().getName()); // 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger","trigroup1")// 定义标识符 .usingJobData("message", "hello mytrigger1")// 传入自定义参数 .usingJobData("doubleTriggerValue", 2.0D)// 传入自定义参数 .startNow()// 定义立即执行 .withSchedule(SimpleScheduleBuilder .simpleSchedule() .withIntervalInSeconds(2) .repeatForever())// 定义执行频度 .build(); // 创建 Scheduler 实例 SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler(); // 绑定 JobDetail 和 trigger scheduler.scheduleJob(jobDeatil, trigger); // 执行任务 scheduler.start(); // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Time Is : " + sf.format(date)); } }
2.HelloJob类改造
package com.myimooc.helloquartz.two; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobDataMap; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.TriggerKey; /** * 编写 自定义任务 * @author ZhangCheng on 2017-06-26 * */ public class HelloJob implements Job{ // 方式二:getter和setter获取 // 成员变量 与 传入参数的key一致 private String message; private Float floatJobValue; private Double doubleTriggerValue; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Float getFloatJobValue() { return floatJobValue; } public void setFloatJobValue(Float floatJobValue) { this.floatJobValue = floatJobValue; } public Double getDoubleTriggerValue() { return doubleTriggerValue; } public void setDoubleTriggerValue(Double doubleTriggerValue) { this.doubleTriggerValue = doubleTriggerValue; } @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Exec Time Is : " + sf.format(date)); // 编写具体的业务逻辑 //System.out.println("Hello World!"); JobKey key = context.getJobDetail().getKey(); System.out.println("My name and group are : " + key.getName() + " : " + key.getGroup()); TriggerKey trkey = context.getTrigger().getKey(); System.out.println("My Trigger name and group are : " + trkey.getName() + " : " + trkey.getGroup()); // 方式一:Map中直接 获取自定义参数 JobDataMap jdataMap = context.getJobDetail().getJobDataMap(); JobDataMap tdataMap = context.getTrigger().getJobDataMap(); String jobMsg = jdataMap.getString("message"); Float jobFloatValue = jdataMap.getFloat("floatJobValue"); String triMsg = tdataMap.getString("message"); Double triDoubleValue = tdataMap.getDouble("doubleTriggerValue"); System.out.println("jobMsg is : " + jobMsg); System.out.println("jobFloatValue is : " + jobFloatValue); System.out.println("triMsg is : " + triMsg); System.out.println("triDoubleValue is : " + triDoubleValue); // 方式一:Map中直接获取 获取自定义参数 JobDataMap jobDataMap = context.getMergedJobDataMap(); jobMsg = jobDataMap.getString("message"); jobFloatValue = jobDataMap.getFloat("floatJobValue"); triMsg = jobDataMap.getString("message"); triDoubleValue = jobDataMap.getDouble("doubleTriggerValue"); System.out.println("jobMsg is : " + jobMsg); System.out.println("jobFloatValue is : " + jobFloatValue); System.out.println("triMsg is : " + triMsg); System.out.println("triDoubleValue is : " + triDoubleValue); // 方式二:getter和setter获取 System.out.println("message is : " + this.message); System.out.println("jobFloatValue is : " + this.floatJobValue); System.out.println("triDoubleValue is : " + this.doubleTriggerValue); } }
2-5 浅谈Trigger
Trigger是什么
Quartz中的触发器用来告诉调度程序作业什么时候触发
即Trigger对象时用来触发执行Job的
Quartz框架中的Trigger示意图
触发器通用属性
JobKey:表示job实例的标识,触发器被触发时,该指定的job实例会执行
StartTime:表示触发器的时间表首次被触发的时间,它的值的类型是Java.util.Date
EndTime:指定触发器的不再被触发的时间,它的值的类型是Java.util.Date
代码演示
1.HelloJob类改造
package com.myimooc.helloquartz.three; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.quartz.JobKey; import org.quartz.Trigger; /** * 自定义任务 触发器通用属性 * @author ZhangCheng on 2017-06-26 * */ public class HelloJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Exec Time Is : " + sf.format(date)); Trigger currentTrigger = context.getTrigger(); System.out.println("Start Time Is : " + sf.format(currentTrigger.getStartTime())); System.out.println("End Time Is : " + sf.format(currentTrigger.getEndTime())); JobKey jobKey = currentTrigger.getJobKey(); System.out.println("JobKey info : " + " jobName : " + jobKey.getName() + " jobGroup : " + jobKey.getGroup()); } }
2.HelloScheduler类改造
package com.myimooc.helloquartz.three; import java.text.SimpleDateFormat; 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; /** * 任务调度类 触发器通用属性 * @author ZhangCheng on 2017-06-26 * */ public class HelloScheduler { public static void main(String[] args) throws SchedulerException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Time Is : " + sf.format(date)); // 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定 JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class) .withIdentity("myjob", "jobgroup1")// 定义标识符 .build(); // 获取距离当前时间3秒后的时间 date.setTime(date.getTime() + 3000); // 获取距离当前时间6秒后的时间 Date endDate = new Date(); endDate.setTime(endDate.getTime() + 6000); // 创建一个 Trigger 实例,定义该 job 立即执行,并且每隔两秒重复执行一次,直到永远 Trigger trigger = TriggerBuilder.newTrigger() .withIdentity("myTrigger","trigroup1")// 定义标识符 .startAt(date)// 定义3秒后执行 .endAt(endDate)// 定义6秒后结束 .withSchedule(SimpleScheduleBuilder .simpleSchedule() .withIntervalInSeconds(2) .repeatForever())// 定义执行频度 .build(); // 创建 Scheduler 实例 SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler(); // 绑定 JobDetail 和 trigger scheduler.scheduleJob(jobDeatil, trigger); // 执行任务 scheduler.start(); } }
2-6 SimpleTrigger
SimpleTrigger的作用
在一个指定时间段内执行一次作业任务
或是在指定的时间间隔内多次执行作业任务
需要注意的点
重复次数可以为0,正整数或是SimpleTrigger.REPEAT_INDEFINITELY常量值
重复执行间隔必须为0或长整数
一旦被指定了endTime参数,那么它会覆盖重复次数参数的效果
代码演示
1.HelloJob类改造
package com.myimooc.helloquartz.four; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; /** * SimpleTrigger 演示 * @author ZhangCheng on 2017-06-26 * */ public class HelloJob implements Job{ @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Exec Time Is : " + sf.format(date)); System.out.println("Hello World!"); } }
2.HelloScheduler类改造
package com.myimooc.helloquartz.four; import java.text.SimpleDateFormat; 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.SimpleTrigger; import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; /** * SimpleTrigger 演示 * @author ZhangCheng on 2017-06-26 * */ public class HelloScheduler { public static void main(String[] args) throws SchedulerException { // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Current Time Is : " + sf.format(date)); // 创建一个 JobDetail 实例,将该实例与 HelloJob 实例绑定 JobDetail jobDeatil = JobBuilder.newJob(HelloJob.class) .withIdentity("myjob", "jobgroup1")// 定义标识符 .build(); // 获取距离当前时间4秒钟之后的具体时间 date.setTime(date.getTime() + 4000); // 获取距离当前时间6秒钟之后的具体时间 Date endDate = new Date(); endDate.setTime(endDate.getTime() + 6000); // 距离当前时间4秒钟后首次执行任务,之后每隔2秒钟重复执行一次任务 // 知道距离当前时间6秒钟之后为止 SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder .newTrigger() .withIdentity("myTrigger","trigroup1")// 定义标识符 .startAt(date) .endAt(endDate) .withSchedule(SimpleScheduleBuilder .simpleSchedule() .withIntervalInSeconds(2) .withRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY)) .build(); // 创建 Scheduler 实例 SchedulerFactory sfact = new StdSchedulerFactory(); Scheduler scheduler = sfact.getScheduler(); scheduler.scheduleJob(jobDeatil, trigger); scheduler.start(); } }
2-7 CronTrigger
CronTrigger的作用
基于日历的作业调度器,而不是像SimpleTrigger那样精确指定间隔时间,比SimpleTrigger更常用
Cron表达式
用于配置CronTrigger实例
是由7个子表达式组成的字符串,描述了时间表的详细信息
格式:[秒][分][小时][日][月][周][年]
Cron表达式特殊字符意义对应表
特殊符号解释
Cron表达式举例
Cron表达式小提示
L和W可以一组合使用
周字段英文字母不区分大小写即MON与mon相同
利用工具,在线生成
2-8 浅谈Scheduler
Scheduler工厂模式
所有的Scheduler实例应该由SchedulerFactory来创建
SchedulerFactory类图
回顾Quartz三个核心概念
调度器
任务
触发器
示意图
Scheduler的创建方式
StdSchedulerFactory
使用一组参数(Java.util.Properties)来创建和初始化Quartz调度器
配置参数一般存储在quartz.properties中
调用getScheduler方法就能创建和初始化调度器对象
Scheduler的主要函数
// 绑定 jobDetail 和 trigger,将它注册进 Scheduler 当中
Date scheduleJob(JobDetail jobDetail, Trigger trigger)
// 启动 Scheduler
void start()
// 暂停 Scheduler
void standby()
// 关闭 Scheduler
void shutdown()
2-9 QuartzProperties文件
quartz.properties组成部分
调度器属性
线程池属性
作业存储设置
插件配置
调度器属性
线程池属性
threadCount:工作线程数量
threadPriority:工作线程优先级
org.quartz.threadPool.class:配置线程池实现类
作业存储设置
描述了在调度器实例的生命周期中,Job和Trigger信息是如何被存储的
插件配置
满足特定需求用到的Quartz插件的配置
第三章:Spring、Quartz大合体
3-1 搭建工程
基于Maven创建一个简单的SpringMVC工程,学习时,使用springboot框架。
项目POM文件
<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.myimooc</groupId> <artifactId>springquartz</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springquartz</name> <url>http://maven.apache.org</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> <version>2.3.0</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> </project>
项目目录结构
3-2 Quartz和Spring大合体
使用Quartz配置作业两种方式
MethodInvokingJobDetailFactoryBean
JobDetailFactoryBean
方式一:使用MethodInvokingJobDetailFactoryBean
1.调用myBean的printMessage方法
2.MyBean类
方式二:使用JobDetailFactoryBean
1.需要给作业传递数据,想要更加灵活的话就是用这种方式
2.FirstScheduleJob类
3.AnotherBean类
代码演示:
演示说明:教学基于xml进行配置,学习时基于javaconfig进行配置。
1.编写MyBean类
package com.myimooc.springquartz.quartz; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.stereotype.Component; /** * 方式一:使用MethodInvokingJobDetailFactoryBean 演示 * @author ZhangCheng on 2017-06-28 * */ @Component public class MyBean { public void printMessage(){ // 打印当前的执行时间,格式为2017-01-01 00:00:00 Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("MyBean Executes!" + sf.format(date)); } }
2.编写AnotherBean类
package com.myimooc.springquartz.quartz; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.stereotype.Component; /** * 方式二:使用JobDetailFactoryBean 演示 * @author ZhangCheng on 2017-06-28 * */ @Component public class AnotherBean { public void printAnotherMessage(){ Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("I am AnotherBean." + sf.format(date)); } }
3.编写FirstScheduledJob类
package com.myimooc.springquartz.quartz; import java.text.SimpleDateFormat; import java.util.Date; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; /** * 方式二:使用JobDetailFactoryBean 演示 * @author ZhangCheng on 2017-06-28 * */ public class FirstScheduledJob extends QuartzJobBean { private AnotherBean anotherBean; public void setAnotherBean(AnotherBean anotherBean) { this.anotherBean = anotherBean; } @Override protected void executeInternal(JobExecutionContext arg0) throws JobExecutionException { Date date = new Date(); SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("FirstScheduledJob Excutes!" + sf.format(date)); this.anotherBean.printAnotherMessage(); } }
4.编写QuartzConfig类
package com.myimooc.springquartz.config; import org.quartz.JobDataMap; import org.quartz.JobDetail; import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.quartz.CronTriggerFactoryBean; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; import com.myimooc.springquartz.quartz.AnotherBean; import com.myimooc.springquartz.quartz.FirstScheduledJob; import com.myimooc.springquartz.quartz.MyBean; /** * Quartz 配置类 * @author ZhangCheng on 2017-06-28 * */ @Configuration public class QuartzConfig { @Autowired private MyBean myBean; @Autowired private AnotherBean anotherBean; /** * 方式一:使用MethodInvokingJobDetailFactoryBean * @return */ @Bean public MethodInvokingJobDetailFactoryBean methodInvokingJobDetailFactoryBean(){ MethodInvokingJobDetailFactoryBean mb = new MethodInvokingJobDetailFactoryBean(); mb.setTargetObject(myBean);// 指定要运行的类 mb.setTargetMethod("printMessage");// 指定要允许类中的那个方法 return mb; } /** * 方式二:使用JobDetailFactoryBean * @return */ @Bean public JobDetailFactoryBean jobDetailFactoryBean(){ JobDetailFactoryBean jb= new JobDetailFactoryBean(); jb.setJobClass(FirstScheduledJob.class);// 指定要运行的类 JobDataMap jobDataMap = new JobDataMap(); jobDataMap.put("anotherBean", anotherBean); jb.setJobDataMap(jobDataMap);// 设置传入自定义参数 jb.setDurability(true); return jb; } /** * 配置 SimpleTriggerFactoryBean * @return */ @Bean public SimpleTriggerFactoryBean simpleTriggerFactoryBean(){ SimpleTriggerFactoryBean sb = new SimpleTriggerFactoryBean(); sb.setJobDetail(methodInvokingJobDetailFactoryBean().getObject());// 设置需要绑定的 jobDetail sb.setStartDelay(1000L);// 距离当前时间1秒后执行 sb.setRepeatInterval(2000L);// 之后每隔2秒执行一次 return sb; } /** * 配置 SimpleTriggerFactoryBean * @return */ @Bean public CronTriggerFactoryBean cronTriggerFactoryBean(){ CronTriggerFactoryBean cb = new CronTriggerFactoryBean(); cb.setJobDetail(jobDetailFactoryBean().getObject());// 设置需要绑定的 jobDetail cb.setStartDelay(1000L);// 距离当前时间1秒后执行 cb.setCronExpression("0/5 * * ? * *");// 设置 Cron 表达式,之后每隔5秒执行一次 return cb; } /** * 配置 SchedulerFactoryBean * @return */ @Bean public SchedulerFactoryBean schedulerFactoryBean(){ SchedulerFactoryBean sb= new SchedulerFactoryBean(); // 配置 JobDetails JobDetail[] jobDetails = new JobDetail[2]; jobDetails[0] = methodInvokingJobDetailFactoryBean().getObject(); jobDetails[1] = jobDetailFactoryBean().getObject(); sb.setJobDetails(jobDetails); // 配置 Trigger Trigger[] triggers = new Trigger[2]; triggers[0] = simpleTriggerFactoryBean().getObject(); triggers[1] = cronTriggerFactoryBean().getObject(); sb.setTriggers(triggers); return sb; } }
第四章:课程总结
4-1 课程总结
课程回顾
Timer
Quartz
Quartz&Spring融合
第五章:Spring boot QuartzConfig另种写法
从上面的例子QuartzConfig中看出autowired中注入了MyBean和AnotherBean。其实可以不用写这个,在方法中写也一样,因为方法中也是注入关系
上面的图就列举了方法注入,同理可得其他,只是方法名称不能乱写,不要一一对应。
下面就列举了2个不同的实例job。
分别创建了2个job,名称分别为JobOneService和JobTwoService
创建QuartzConfig.class
@Configuration public class QuartzConfig { @Bean("jobOneDetail") public MethodInvokingJobDetailFactoryBean jobOneDetailFactoryBean(JobOneService jobOneService) { MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); jobDetail.setTargetObject(jobOneService); // 是否并发执行 jobDetail.setConcurrent(true); //需要执行的方法-对应JobOneService的方法 jobDetail.setTargetMethod("task"); return jobDetail; } @Bean("jobOneTrigger") public SimpleTriggerFactoryBean jobOneTrigger(JobDetail jobOneDetail) { SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); trigger.setJobDetail(jobOneDetail); trigger.setRepeatCount(0); return trigger; } @Bean("jobTwoDetail") public MethodInvokingJobDetailFactoryBean jobTwoDetailFactoryBean(JobTwoService jobTwoService) { MethodInvokingJobDetailFactoryBean jobDetail = new MethodInvokingJobDetailFactoryBean(); jobDetail.setTargetObject(jobTwoService); // 是否并发执行 jobDetail.setConcurrent(true); //需要执行的方法-对应jobTwoService的方法 jobDetail.setTargetMethod("task"); return jobDetail; } @Bean("jobTwoTrigger") public CronTriggerFactoryBean cronTriggerFactoryBean(JobDetail jobTwoDetail) { CronTriggerFactoryBean trigger = new CronTriggerFactoryBean(); trigger.setJobDetail(jobTwoDetail); // cron表达式,每过10秒执行一次 trigger.setCronExpression("0/5 * * * * ?"); return trigger; } @Bean public SchedulerFactoryBean schedulerFactoryBean(Trigger jobOneTrigger, Trigger jobTwoTrigger) { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); // 延时启动,应用启动5秒后 schedulerFactoryBean.setStartupDelay(5); schedulerFactoryBean.setTriggers(jobOneTrigger, jobTwoTrigger); return schedulerFactoryBean; } }
1、MethodInvokingJobDetailFactoryBean setTargetMethod 这个就是执行的方法,没有这个都不知道执行什么。
2、看上面的Bean里面的名称都是一一对应的
@Component @EnableScheduling public class JobOneService { public void task() { System.out.println("JobOneService" + new Date()); } } @Component @EnableScheduling public class JobTwoService { public void task() { System.out.println("JobTwoService" + new Date()); } }
将任务进行配置,项目启动就会开始执行了。