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>
