使用Quartz定时任务时,无法注入Spring Bean的问题解决
在做定时任务时,需要继承Job来重写execute(),如果直接使用@Autowired,运行时会报出空指针异常
原因:在quartz框架中,Job 是通过反射出来的实例,不受spring的管理。
解决方案:
重写JobFactory类
@Component
public class JobFactory extends SpringBeanJobFactory {
@Autowired
private AutowireCapableBeanFactory beanFactory;
/**
* 这里覆盖了super的createJobInstance方法,对其创建出来的类再进行autowire。
*
* @param bundle
* @return
* @throws Exception
*/
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
Object jobInstance = super.createJobInstance(bundle);
beanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
在spring配置文件内配置SchedulerFactoryBean
,使用刚才自定义的JobFactory
,注意结构!
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" id="schedulerFactoryBean" lazy-init="true" autowire="no">
<property name="triggers">
<list>
<ref bean="cronTrigger"/>
</list>
</property>
<property name="jobFactory" ref="jobFactory"/>
</bean>
这时直接在实现Job的方法中@Autowired就可以了
还有另一种方案,创建工具类SpringContextJobUtil
,实现ApplicationContextAware
接口,此工具类会在spring容器启动后,自动加载,使用其提供的getBean
方法获取想要的bean即可