前言
在做定时任务时,往往都会在Job的业务逻辑中依赖其他业务的来完成整个任务。
在使用Quartz时,Job的创建是new出来的,所以在Job使用@Autowired自动装配注解是无效的。
为了在job中,能实现自动装配的功能,则需要通过自定义Job的工厂来实现这个需求。
开始
第一步:自定义Job工厂类
/**
* 自定义Job工厂类
* <p>
* job的初始化时quartz在执行时new出来的。不受spring的管理,无法注入相关的依赖bean
* 所以需要在job在被创建的时候,使用AutowireCapableBeanFactory实现自动转配Job实例
* <p>
* AutowireCapableBeanFactory,可以利用这个接口自动装配那些不在spring控制范围内的bean实例
*/
@Component
public class AutowireJobFactory extends AdaptableJobFactory {
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
//自动装配实例
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
第二步:配置
@Configuration
public class QuartzConfig {
//自定义Job工厂类
@Autowired
private ConvertJobFactory convertJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactory() {
SchedulerFactoryBean bean = new SchedulerFactoryBean();
bean.setJobFactory(convertJobFactory);
return bean;
}
}
第三步:Quartz任务添加工具类
@Component
public class QuartzManager {
@Autowired
private SchedulerFactoryBean schedulerFactory;
public void addJob(Class<? extends Job> jobClass, String jobName, String groupName, String cron) {
try {
//创建jobDetail实例,绑定Job实现类
//指明job的名称,所在组的名称,以及绑定job类
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(jobName, groupName) //任务名称和组构成任务key
.build();
//定义调度触发规则
//使用cornTrigger规则
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity(jobName, groupName)//触发器key
.startAt(DateBuilder.futureDate(1, DateBuilder.IntervalUnit.SECOND))
.withSchedule(CronScheduleBuilder.cronSchedule(cron))
.startNow().build();
Scheduler scheduler = schedulerFactory.getScheduler();
//把作业和触发器注册到任务调度中
scheduler.scheduleJob(jobDetail, trigger);
// 启动
if (!scheduler.isShutdown()) {
scheduler.start();
}
} catch (SchedulerException e) {
e.printStackTrace();
}
}
}
第四步:编写Job
@Component
public class Cad2ImgConvertQuartz implements Job, InitializingBean {
@Autowired
private QuartzManager quartzManager;
/**
* Job类需要实现的方法,具体在这个方案里面实现任务的业务逻辑
*/
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//TODO 业务逻辑
}
/**
* InitializingBean类需要实现的方法,作用是在服务初始化后执行。
* 这里服务初始化后,直接把Job添加到任务调度器里
*/
@Override
public void afterPropertiesSet() throws Exception {
//添加当前任务
quartzManager.addJob(this.getClass(),
this.getClass().getSimpleName(),
QuartzConfig.GROUP_NAME,
QuartzConfig.cron);
}
}
以上就完成了注入Bean的方式,动态添加quartz任务