Spring通过DI和IoC方式给大家提供了很多便捷操作,很多地方不需要编写大量代码,仅需要通过配置文件加简单的注解就可以完成,最近在项目开发过程中用到Quartz,借此学习并跟大家分享一下。
Quartz作为老牌Scheduler执行工具,提供了很多便利,学习起来也比较方便,由于之前进行网站开发相对较少走了不少弯路。
首先,项目需要通过maven引入相关开发包,从maven repository引入项目即可。
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
之后,配置Quartz文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="schedulerFactory" class="org.quartz.impl.StdSchedulerFactory"></bean>
</beans>
再后,可以编写Job文件,为了演示方便,仅写做了简单打印操作,注意编写时候需要集成实现Job累的execute方法。
package cn.cnic.datapub.job;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
public class HelloJob implements Job
{
private String name;
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.getName();
}
@Override
public void execute(JobExecutionContext context)
throws JobExecutionException
{
System.out.println("execute "+this.name);
}
}
接下来,调用的部分代码主要分为两个步骤,生成JobDetail,生成Trigger,然后将其注册到Scheduler中。
//获取Scheduler
Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
//生成JobDetail
JobDetail job = newJob(HelloJob.class).withIdentity("name", "group")
.usingJobData("name", "myname").build();
//生成Trigger 2s,10s后执行
Trigger trigger = newTrigger()
.withIdentity(triggerKey(id, name))
.withSchedule(
simpleSchedule().withIntervalInSeconds(2)
.repeatForever())
.startAt(futureDate(10, SECOND)).build();
//注册到schedule中
scheduler.scheduleJob(job, trigger);
注意点:
- Scheduler获取的对象是单例!单例!单例!
- 在执行JobDetail的时候可以通过usingJobData来设置你定义的Job中的参数,进行实现在Job内部实现你的一些业务流程。
- newJob与newTrigger或者其他的变量不是写错了,是通过静态方式引入的
java
import static org.quartz.DateBuilder.futureDate;
import static org.quartz.DateBuilder.IntervalUnit.SECOND;
import static org.quartz.JobBuilder.newJob;
import static org.quartz.SimpleScheduleBuilder.simpleSchedule;
import static org.quartz.TriggerBuilder.newTrigger;
import static org.quartz.TriggerKey.triggerKey;
最后,可以在执行过程中动态修改或删除任务,但是执行过程中你需要记录你的Job或者Trigger的group和name的值,形成JobKey和TriggerKey才操作。
//构建JobKey,删除scheduler中的Job
JobKey jk = new JobKey(id, name);
scheduler.deleteJob(jk);
//构建新的Trigger替换之前的Trigger
TriggerKey tk = new TriggerKey(id, name);
Trigger trigger = newTrigger()
.withIdentity(triggerKey(id, name))
.withSchedule(
simpleSchedule().withIntervalInSeconds(1)
.repeatForever())
.startAt(futureDate(10, SECOND)).build();
scheduler.rescheduleJob(tk, trigger);
需要说明的几点:
- 在Quartz中StdSchedulerFactory构造的Scheduler是简单、单例、静态的,所以你不需要自行构建类注入到Spring框架中,笔者曾写了一个映射,操作Scheduler,引入了一堆发现删除的时候都无法使用了,听者足戒。
- Scheduler中构造“group”和“name”的时候就已经为分类进行准备,它们构成的 JobKey或者TriggerKey,就是为了方便大家操作Scheduler的。
- Scheduler中的Trigger与Job是多对多的,由此相当于你做了一个Map操作进行Scheduler,并且可以通过影响Trigger达到控制多个Job的效果。