注入null原因 : 项目中利用Quartz可以实现定时任务, Job类里的 注入 无法用常规的 属性注入,Job类的对象实例化是在Quartz中进行的有自己的JobContext,但是需要注入调用的 类是在spring中ApplicationContext实例化的,所以导致为空,调用失败 的情况。
package com.xxx.task;
import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.scheduling.quartz.AdaptableJobFactory;
import org.springframework.stereotype.Component;
@Component
public class MyJobFactory extends AdaptableJobFactory{
//这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.
@Autowired
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
package com.xxxx.task;
import java.io.IOException;
import java.util.Properties;
import org.quartz.Scheduler;
import org.quartz.ee.servlet.QuartzInitializerListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
@Configuration
public class QuartzConfigration {
public static final Logger log = LoggerFactory.getLogger(QuartzConfigration.class);
@Autowired
private MyJobFactory jobFactory;
@Bean(name = "SchedulerFactory")
public SchedulerFactoryBean schedulerFactoryBean() throws IOException {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setQuartzProperties(quartzProperties());
factory.setOverwriteExistingJobs(true);
//延时启动 应用程序 启动 5秒后
factory.setStartupDelay(1);
//替换从spring创建实例 使得spring注入 正常运行
factory.setJobFactory(jobFactory);
return factory;
}
@Bean
public Properties quartzProperties() throws IOException {
PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
propertiesFactoryBean.setLocation(new ClassPathResource("/quartz.properties"));
// 在quartz.properties中的属性被读取并注入后再初始化对象
propertiesFactoryBean.afterPropertiesSet();
return propertiesFactoryBean.getObject();
}
/*
* quartz初始化监听器
*/
@Bean
public QuartzInitializerListener executorListener() {
return new QuartzInitializerListener();
}
/*
* 通过SchedulerFactoryBean获取Scheduler的实例
*/
@Bean(name = "Scheduler")
public Scheduler scheduler() throws IOException {
///用于quartz集群,QuartzScheduler 启动时更新己存在的Job,这样就不用每次删除已存在的job记录
//schedulerFactoryBean().setOverwriteExistingJobs(true);
//QuartzScheduler 延时启动,应用启动完10秒后 QuartzScheduler 再启动
//schedulerFactoryBean().setStartupDelay(10);
schedulerFactoryBean().setAutoStartup(true);
return schedulerFactoryBean().getScheduler();
}
}
通过自定义factory实例化即可正常在quartz相关类中使用注入。