前言
网上搜索各种博客案例我们可以发现大多数Quartz和Spring的整合都是借助spring的xml配置文件来定义各种bean(Trigger、Scheduler、JobDetail等)来实现Quartz进行作业调度,其实现原理是通过配置文件或者注解来定义各种bean之间的引用关系,从而编码实现Quartz的整合。但是这种方式需要书写的配置文件太多,并且需要添加新的作业进行调度时的可扩展性太差,为此接下来借助Springboot来减少配置,自己编码实现可以更好的进行新增作业借助Quartz调度。
正题(案列)
首先Quartz的三要素是必不可少的(Trigger、Scheduler、JobDetail),
接下来需要考虑的就是如何使得这三者之间的关系通过编码动态实现,而不是像我们学Quartz的时候写demo一样,每写一个JobDetail还得写一个Trigger,还得通过Scheduler.scheduler注册两者。
预先定义Job
将所有的Job实现IntegerCallable接口作为标识,便于动态获取所有的Job实现类
public interface IntegerCallable extends Callable<Integer> {
int STATUS_CODE_OK = 0;
}
@Component
public class Duty implements IntegerCallable {
private static Logger LOGGER = LoggerFactory.getLogger(Duty.class);
@Autowired
public MapreduceDuty(MapreduceConfig mapreduceConfig) {
this.mapreduceConfig = mapreduceConfig;
}
public MapreduceDuty() {
}
@Override
public Integer call() throws Exception {
//此处定义Job中的execute方法中的执行逻辑即Job所要执行的任务
return STATUS_CODE_OK;
}
}
定义TriggerFactory
createTrigge根据配置文件中不同的前缀创建不同的Trigger
public static class TriggerFactory {
private static Trigger createTrigger(){}
private static Trigger createCronTrigger{}
private static Trigger createIntervalTrigger{}
private static Trigger createOneTimeTrigger{}
}
配置文件格式
将类名写成如xxx-xxxx-xxx的格式,
duty-on-call=cron:* * * * * ?
定时执行(cron表达式)
xxx-xxxx-xxx=interval:2h
间隔执行
xxx-xxxx-xxx=one-time
执行一次
统一Job抽象类
public class UnifiedJob implements Job {
public void execute(){
//这里反射调用每个标识Job即IntegerCallable子类的call方法
}
public UnifiedJob newUnifiedJob(){
//创建Job
}
}
实现ApplicationListener 完成动态调度
根据ApplicationListener的原理,其onApplicationEvent(ContextRefreshedEvent event) 方法会在初始化所有的bean之后被调用,因此我们可以在这里进行scheduler的创建、启动,以及注册trigger和job
public class JobScheduler implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
refresh();
}
private void refresh() {
//1.获取所有的标识Job即IntegerCallable子类,生成UnifiedJob
//2.创建每个Job的Trigger 关联配置文件的表达式
//3.创建scheduler
//4.注册trigger和job
//5.启动scheduler
}
@PreDestroy
public void onStop() {
//关闭scheduler
}
}
以上只是巧妙的借助ApplicationListener来实现Quartz的整合,只写了大概的思路,写的有点糙,大家有更好的整合方法欢迎分享交流。