Quartz简介
Quartz是Job Scheduling(任务调度)领域的开源项目,可单独使用,也可和JavaSE,EE进行组合,是一个任务调度管理系统,可在特定的时间内执行特定的任务,如想在Java中使用Quartz,则只需将Quartz的jar包导入到项目中即可.
Quartz相关介绍
Jobs:任务
是实际想要执行的操作,只需要实现Job接口即可.
package com.dong.controller;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class jobtask implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//所要执行的操作
}
}
JobDetail对象:
public static void main(String[] args) {
JobDetail jobtask = newJob(jobTask.class)
.withIdentity("jobone","jobA")
.build();
}
JobDetail对象,在上面的实例中,引入了JobBuilder类的静态方法newJob来创建job实例,withIdentity用来表示job的名字和所属组,build()方法则返回一个JobDetail实例.
JobDetail的源码解释为:
/**
*Conveys the detail properties of a given <code>Job</code> instance. JobDetails are
* to be created/defined with {@link JobBuilder}.
*
* <p>
* Quartz does not store an actual instance of a <code>Job</code> class, but
* instead allows you to define an instance of one, through the use of a <code>JobDetail</code>.
* </p>
**/
即Quartz不能存储Job实例,当Quartz需要Job的信息时,可定义JobDetail来存储Job属性,JobDetail通过JobBuilder创建.
public static JobBuilder newJob(Class <? extends Job> jobClass) {
JobBuilder b = new JobBuilder();
b.ofType(jobClass);
return b;
}
Job的调度是通过scheduler实例,scheduler传入JobDetail对象和Trigger对象,JobDetail对象则在构造的过程中传入Job对象的class对象,可以看出这里使用反射的机制进行创建Job对象,当每次调用execute方法,则创建一个Job对象,然后丢弃该对象的引用,因此,Job对象必须有一个空参的构造器,其次,Job对象的属性值不会保存,如果想在Job对象执行中使用配置和属性,则可以使用JobDataMap.
public class jobTask implements Job {
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
String name =context.getJobDetail().getJobDataMap().getString("name");
System.out.println("name");
}
public static void main(String[] args) {
JobDetail jobtask = newJob(jobTask.class)
.withIdentity("jobone","jobA")
.usingJobData("name","land")
.build();
}
}
JobDataMap可以包含数据对象,可在Job执行过程中,使用该对象的数据.
Trigger:触发器
Trigger公共属性:TriggerKey属性,表明Trigger身份,jobKey:Trigger被触发时被执行的Job身份,startTime属性:设置第一次触发时间,endTime属性:触发失效时间.错过触发misfire.
Trigger优先级,默认为5,可以是任意数值,注意只有同一时刻触发的trigger之间才会比较优先级.
calendar:不是Java的日历对象,这个对象用于从trigger的调度计划中排除时间段,创建Calendar需要实现Calendar接口,然后实例化改对象,并添加到scheduler对象中.对于一整天的排除,则可以使用HolidayCalendar对象,方法modifiedByCalendar()方法将在任务调度时,排除在该时间段的任务.
public static void main(String[] args) {
HolidayCalendar holidayCalendar = new HolidayCalendar();
holidayCalendar.addExcludedDate("xxx");
Trigger trigger = newTrigger()
.withIdentity("triggerone")
.forJob("job")
.withSchedule(dailyAtHourAndMinute(12,00))
.modifiedByCalendar("holidayCalendar")
.build();
}
Trigger两个子类有Siimple Trigger,Cron Trigger.
Simple Trigger:在特定的时间点支持,或者在特定的时间点执行,然后以特定的时间间隔执行.
CronTrigger 基于日历概念,使用CronTrigger需要指定时间表,Cron Expressions是用来定义日历的表达式,“0 0 12?* WED“ - 这意味着”每个星期三下午12:00“。
创建和Triigger对象相同,可以通过设置触发器的名字,开始时间,结束时间,执行次数,调度器,指定Job来实现任务的触发操作.
TriggerListeners和JobListeners:前者用来监听触发器,后者用来监听Job.***只需要实现TriggerListener或JobListeners接口即可,可以扩展JobListenerSupport类或TriggerListenerSupport类, listener与调度程序的ListenerManager一起注册,并配有描述listener希望接收事件的job/触发器的Matcher。
SchedulerListener***,包含各种监听Shceduler的事件,和TriggerListenners与JobListeners类型,需要注册到调度程序的ListennerManager。以JobListener为例:
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
public class JobLis implements JobListener {
@Override
public String getName() {
return "jobpre";
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
System.out.println("Job Start >...");
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
System.out.println("Job end >....");
}
}
可通过jobExecutionContext来获取Job在运行时的一些数据.
Schedule:调度器
可通过StdSchedulerFactory,DirectSchedulerFactory来实现,也可通过schedulerFactory获取.
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
Scheduler scheduler = schedulerFactory.getScheduler();
Quartz在使用前,需要进行实例化,可以使用SchedulerFactory进行实例化,以工厂模式生成一个实例对象,scheduler实例化后,可启动,暂停,停止.除非scheduler启动,才可以进行相应的任务执行操作.
完整的任务调度案例:使用Maven方式创建工程
1.创建工程,pom.xml导入依赖
<?xml version="1.0" encoding="UTF-8"?>
<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.dong.quartz</groupId>
<artifactId>quartz_helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加Scheduled坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- Sprng tx 坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
</dependencies>
</project>
2.创建Job类
package com.dong.controller;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Component;
@Component
public class JobIns implements Job {
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
System.out.println("执行 Ququ ...." );
}
}
3.创建JobListeners
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobListener;
public class JobLis implements JobListener {
@Override
public String getName() {
return "jobpre";
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
String name = jobExecutionContext.getJobDetail().getJobDataMap().getString("name");
System.out.println("Job Start >...");
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException e) {
System.out.println("Job end >....");
}
}
4.创建Trigger Listenner
package com.dong.controller;
import org.quartz.JobExecutionContext;
import org.quartz.Trigger;
import org.quartz.TriggerListener;
public class TriggerLis implements TriggerListener {
@Override
public String getName() {
return "triggerpre";
}
@Override
public void triggerFired(Trigger trigger, JobExecutionContext jobExecutionContext) {
}
@Override
public boolean vetoJobExecution(Trigger trigger, JobExecutionContext jobExecutionContext) {
return false;
}
@Override
public void triggerMisfired(Trigger trigger) {
}
@Override
public void triggerComplete(Trigger trigger, JobExecutionContext jobExecutionContext, Trigger.CompletedExecutionInstruction completedExecutionInstruction) {
System.out.println("trigger complete > .....");
}
}
5.创建配合类,Simplejob,Trigger,Scheduler
package com.dong.config;
import com.dong.controller.JobLis;
import com.dong.controller.TriggerLis;
import com.dong.controller.JobIns;
import org.quartz.Scheduler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.quartz.JobDetailFactoryBean;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean;
@Configuration
public class QuartzConfig {
@Bean
public JobDetailFactoryBean jobDetailFactoryBean(){
JobDetailFactoryBean jobDetailFactory = new JobDetailFactoryBean();
jobDetailFactory.setJobClass(JobIns.class);
return jobDetailFactory;
}
@Bean
public SimpleTriggerFactoryBean simpleTriggerFactoryBean(JobDetailFactoryBean jobDetailFactory){
SimpleTriggerFactoryBean simpleTriggerFactory = new SimpleTriggerFactoryBean();
simpleTriggerFactory.setJobDetail(jobDetailFactory.getObject());
simpleTriggerFactory.setRepeatInterval(2000);
simpleTriggerFactory.setRepeatCount(20);
return simpleTriggerFactory;
}
@Bean
public SchedulerFactoryBean schedulerFactoryBean(SimpleTriggerFactoryBean simpleTriggerFactory){
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setTriggers(simpleTriggerFactory.getObject());
schedulerFactory.setGlobalJobListeners(new JobLis());
schedulerFactory.setGlobalTriggerListeners(new TriggerLis());
return schedulerFactory;
}
}
6.创建启动类
package com.dong.boot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;
@SpringBootApplication
@EnableScheduling
@ComponentScan("com.dong.*")
public class application {
public static void main(String[] args) {
SpringApplication.run(application.class,args);
}
}
7.运行结果为:
Job Start >...
执行 Ququ ....
Job end >....
trigger complete > .....
Job Start >...
执行 Ququ ....
Job end >....
trigger complete > .....
如有异议,敬请指出,与君共勉.