Quartz是一个定时任务调度的框架,在预定的时间到达时,执行某一任务
可认为是JDK的Timer类的扩展
Quartz的核心接口
Scheduler – 核心调度器
Job – 任务
JobDetail – 任务描述
Trigger -- 触发器
SimpleTrigger只执行一次或在给定时间触发并重复N次
CronTriggers:像日历那样按日程来触发任务, 使用cron表达式
代码示例
public class MyJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { System.out.println("Hello world"); } }
public class QuartzExample { public void run() throws Exception { // 调度器 SchedulerFactory sf = new StdSchedulerFactory(); Scheduler sched = sf.getScheduler(); // 获取当前时间的下一分钟 Date runTime = evenMinuteDate(new Date()); // 定义job // 在quartz中,有组的概念,withIdentity(名称, 组) JobDetail job = newJob(MyJob.class).withIdentity("job1", "group1").build(); // 定义触发器,每2秒执行一次 Trigger trigger = newTrigger().withIdentity("trigger1", "group1").withSchedule(cronSchedule("0 0/1 * * * ?")).build(); // 定义触发器,在下一分钟启动 // Trigger trigger = newTrigger().withIdentity("trigger1", "group1").startAt(runTime).build(); // 将job注册到调度器 sched.scheduleJob(job, trigger); // 启动调度器 sched.start(); // 模拟handling Thread.sleep(60L * 1000L); // 关闭调度器 sched.shutdown(true); } public static void main(String[] args) throws Exception { QuartzExample example = new QuartzExample(); example.run(); } }
进一步的用法是与Spring整合
public class MyJob extends QuartzJobBean { @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("myJob 执行了............." + context.getTrigger().getKey().getName()); // get("applicationContext")参数是spring配置中applicationContextJobDataKey属性的值, 作为jobmap的key. 这条语句拿到spring容器 ApplicationContext applicationContext = (ApplicationContext) context.getJobDetail().getJobDataMap().get("applicationContext"); System.out.println("获取到的Spring容器是: " + applicationContext); } }
// 实例化spring容器
public class Main { public static void main(String[] args) { new ClassPathXmlApplicationContext("classpath:applicationContext-scheduler.xml"); } }
spring配置文件
<!-- 定义jobDetail --> <bean id ="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- 指定具体的job类 --> <property name ="jobClass" value="com.zx.quartz.MyJob" /> <!-- 指定job的名称 --> <property name="name" value="myJob" /> <!-- 指定job的分组 --> <property name="group" value="jobs" /> <!-- 必须设置为true,如果为false,当没有活动的触发器与之关联时会在调度器中删除该任务 --> <property name="durability" value="true"/> <!-- 指定spring容器的key,如果不设定那么在job类中是获取不到spring容器里的对象的 --> <property name="applicationContextJobDataKey" value="applicationContext"/> </bean> <!-- 另一种方式, 定义job和jobDetial, Job类为普通类即可 <!-- 配置job -- <bean id="myJob" class="com.zx.quartz.MyJob"/> <!-- 配置jobDetail -- <bean id="myJobDetial" class="org.springframework.scheduling.quartz.MethodlnvokingJobDetaiLFactoryBean"> <property name="targetObject"> <ref bean="myJob" /> </property> <property name="targetMethod"> <!-- 要执行的方法名 -- <value>execute</value> </property> </bean> --> <!-- 定义触发器 --> <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="myJobDetail" /> <!-- 每五秒执行一次 --> <property name="cronExpression" value="0/5 * * * * ?" /> </bean> <!-- 定义触发器, 一个job可以有多个trigger, 但一个trigger只能有一个job --> <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>