看了网上很多方案,大多都是实现重载 AdaptableJobFactory,然后利用factory.autowireBean()来注入,我在本地实验,可能版本原因,找不到AdaptableJobFactory类,另辟蹊径,实现了这一版。
一.自实现JobFactory接口MyJobFactory,代码从系统原生SimpleJobFactory拿来,只修改其中一行:
将 return jobClass.newInstance() 改为:
return (Job) SpringContextUtils.getBean(jobClass);
可以看出,默认是newInstance()的,自然无法使用spring注入,修改为从SpringContextUtils里获取就可以达到目的
package com.alimama.qa.platform.makaira.taskScheduler;
import com.alimama.qa.platform.utils.SpringContextUtils;
import org.quartz.Job;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.spi.JobFactory;
import org.quartz.spi.TriggerFiredBundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @program makaira
* @description:
* @author: xiaopeng.sxp
* @create: 2019/05/06 10:22
*/
public class MyJobFactory implements JobFactory {
private final Logger log = LoggerFactory.getLogger(getClass());
protected Logger getLog() {
return log;
}
public Job newJob(TriggerFiredBundle bundle, Scheduler Scheduler) throws SchedulerException {
JobDetail jobDetail = bundle.getJobDetail();
Class<? extends Job> jobClass = jobDetail.getJobClass();
try {
if (log.isDebugEnabled()) {
log.debug(
"Producing instance of Job '" + jobDetail.getKey() +
"', class=" + jobClass.getName());
}
return (Job) SpringContextUtils.getBean(jobClass);
// return jobClass.newInstance();
} catch (Exception e) {
SchedulerException se = new SchedulerException(
"Problem instantiating class '"
+ jobDetail.getJobClass().getName() + "'", e);
throw se;
}
}
}
@Component
public class SpringContextUtils implements ApplicationContextAware {
public static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
SpringContextUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static Object getBean(Class className) {
return applicationContext.getBean(className);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return applicationContext.getBean(name, requiredType);
}
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
public static boolean isSingleton(String name) {
return applicationContext.isSingleton(name);
}
public static Class<? extends Object> getType(String name) {
return applicationContext.getType(name);
}
}
二. 使自定义jobFactory替代系统默认实现
跟踪源代码,发现可以在quartz配置文件里指定 jobFactoryClass ,
在系统resource目录里添加quartz.properties文件,可以从jar包里copy一份 ,添加一句:
org.quartz.scheduler.jobFactory.class: com.alimama.qa.platform.makaira.taskScheduler.MyJobFactory
# Customized Properties file for use by StdSchedulerFactory
# to create a Quartz Scheduler Instance, if a different
# properties file is not explicitly specified.
#
org.quartz.scheduler.instanceName: DefaultQuartzScheduler
org.quartz.scheduler.rmi.export: false
org.quartz.scheduler.rmi.proxy: false
org.quartz.scheduler.wrapJobExecutionInUserTransaction: false
org.quartz.threadPool.class: org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount: 100
org.quartz.threadPool.threadPriority: 5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread: true
org.quartz.jobStore.misfireThreshold: 60000
org.quartz.jobStore.class: org.quartz.simpl.RAMJobStore
org.quartz.scheduler.jobFactory.class: com.alimama.qa.platform.makaira.taskScheduler.MyJobFactory
三. 重启应用,设置断点,看到job里的service已经被注入了