Quartz
Quartz是一个Open Symphony开源组织的一个任务日程管理系统。一个预先确定(被纳入日程)的时间到达时,负责执行(或者通知)其他软件组件的系统。
大致的流程为:
核心调度器(scheduler)
任务(job)
任务描述(jobdetail)
触发器(Trigger)
导入所需的包/依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
核心API:
Scheduler:
需要注册一个调度器,来负责管理任务和任务描述,在通过调用里面的触发器来实现执行,实质为一个容器,在里面进行控制。
JOB:
定义一个所需要执行的任务。
JOBDetail:
定义一个任务执行的描述内容。
Trigger:
SimpleTrigger用来触发只需执行一次或者在定时间触发并且重复N次且每次执行延迟一定时间的任务
如果你需要像日历那样按日程来触发任务,而不是像SimpleTrigger 那样每隔特定的间隔时间触发,CronTriggers通常比SimpleTrigger更有用。
使用CronTrigger的时候,一般为使用Cron Expressions表达式来表达需要执行的时间
Cron表达式被用来配置CronTrigger实例。Cron表达式是一个由7个子表达式组成的字符串。每个子表达式都描述了一个单独的日程细节。这些子表达式用空格分隔,分别表示:
Seconds 秒
Minutes 分钟
Hours 小时
Day-of-Month 月中的天
Month 月
Day-of-Week 周中的天
Year (optional field) 年(可选)
简单的案例,首先是使用SimpleTrigger:
package com.mjf.quartz.example;
import java.util.Date;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SimpleExample {
public void run() throws Exception{
Logger log = LoggerFactory.getLogger(SimpleExample.class);
log.info("-------------初始化----------------");
//定义调度器
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
log.info("-------------初始化调度器----------------");
//获取当前时间的下一分钟
Date runTime = DateBuilder.evenMinuteDate(new Date());
log.info("------------ 调度任务----------------");
//定义任务描述。任务为hellojob
//在任务中,需要定义组,组+job名称是唯一的
JobDetail job = JobBuilder.newJob(HelloQuartz.class).withIdentity("job1", "group1").build();
//定义触发器
//在触发器中,需要定义组,组+trigger名称是唯一的
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build();
//注册到调度器
scheduler.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + runTime);
// 启动调度器
scheduler.start();
log.info("------- Started Scheduler -----------------");
// 等待65秒
log.info("------- Waiting 65 seconds... -------------");
try {
// wait 65 seconds to show job
Thread.sleep(65L * 1000L);
// executing...
} catch (Exception e) {
//
}
// 关闭调度器
log.info("------- Shutting Down ---------------------");
scheduler.shutdown(true);
log.info("------- Shutdown Complete -----------------");
}
public static void main(String[] args) throws Exception {
SimpleExample example = new SimpleExample();
example.run();
}
}
定义一个任务类:
package com.mjf.quartz.example;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 任务
* @author Mao
*/
public class HelloQuartz implements Job {
private static Logger _log = LoggerFactory.getLogger(HelloQuartz.class);
public HelloQuartz(){}
public void execute(JobExecutionContext context)
throws JobExecutionException {
_log.info("Hello World!" + new Date());
}
}
CronTrigger:
package com.mjf.quartz.example;
import java.util.Date;
import org.quartz.CronScheduleBuilder;
import org.quartz.DateBuilder;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CromExample {
public static void main(String[] args) throws Exception {
CromExample example = new CromExample();
example.run();
}
private void run() throws Exception {
Logger log = LoggerFactory.getLogger(CromExample.class);
log.info("----------初始化---------------");
//定义调度器
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
log.info("----------初始化调度器---------------");
//获取当前时间的下一分钟
Date runTime = DateBuilder.evenMinuteDate(new Date());
log.info("------------ 调度任务----------------");
//定义任务和描述
JobDetail job =JobBuilder.newJob(HelloQuartz.class).withIdentity("job1", "group1").build();
//定义触发器
Trigger trigger = TriggerBuilder.newTrigger().withIdentity("trigger1", "group1")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0/1 * * * ?")).build();
//注册到调度器
scheduler.scheduleJob(job, trigger);
log.info(job.getKey() + " will run at: " + runTime);
// 启动调度器
scheduler.start();
log.info("------- Started Scheduler -----------------");
// 等待65秒
log.info("------- Waiting 65 seconds... -------------");
try {
// wait 65 seconds to show job
Thread.sleep(65L * 1000L);
// executing...
} catch (Exception e) {
//
}
// 关闭调度器
log.info("------- Shutting Down ---------------------");
scheduler.shutdown(true);
log.info("------- Shutdown Complete -----------------");
}
}
Spring整合Quartz:
Spring和Quartz的整合,和其他的整合,都是只需要把相关的Quartz类在spring配置文件中进行配置即可。
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<!-- 定义任务bean -->
<bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
<!-- 指定具体的job类 -->
<property name="jobClass" value="com.mjf.quartz.spring.MyJob" />
<!-- 指定job的名称 -->
<property name="name" value="myJob" />
<!-- 指定job的分组 -->
<property name="group" value="jobs" />
<!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中删除该任务 -->
<property name="durability" value="true"/>
<!-- 指定spring容器的key,如果不设定在job中的jobmap中是获取不到spring容器的 -->
<property name="applicationContextJobDataKey" value="applicationContext"/>
</bean>
<!-- 定义触发器 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="myJobDetail" />
<!-- 每一分钟执行一次 -->
<property name="cronExpression" value="0/5 * * * * ?" />
</bean>
<!-- 定义触发器 -->
<!-- 演示:一个job可以有多个trigger; -->
<!-- <bean id="cronTrigger2" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean">
<property name="jobDetail" ref="myJobDetail" />
每一分钟执行一次
<property name="cronExpression" value="0 */1 * * * ?" />
</bean> -->
<!-- 定义调度器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="cronTrigger" />
<!-- <ref bean="cronTrigger2" /> -->
</list>
</property>
</bean>
</beans>
实现类:
首先是一个任务类:
package com.mjf.quartz.spring;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.quartz.QuartzJobBean;
public class MyJob extends QuartzJobBean {
@Override
protected void executeInternal(JobExecutionContext job)
throws JobExecutionException {
System.out.println("mjob执行了" + job.getTrigger().getKey().getName());
ApplicationContext context = (ApplicationContext) job.getJobDetail()
.getJobDataMap().get("applicationContext");
System.out.println("获取的spring容器是:" + context);
}
}
测试类:
package com.mjf.quartz.spring;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyjobMain {
@SuppressWarnings("resource")
public static void main(String[] args) {
new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
}
}
通过这些简单的对quartz的案例便能够对quartz的相关功能做一个相对的了解