使用spring 結(jié)合quartz進(jìn)行定時任務(wù)開發(fā)時,如果直接在job內(nèi)的execute方法內(nèi)使用service 或者mapper對象膳汪,執(zhí)行時唯蝶,出現(xiàn)空指針異常。
問題原因
job對象在spring容器加載時候遗嗽,能夠注入bean粘我,但是調(diào)度時,job對象會重新創(chuàng)建痹换,此時就是導(dǎo)致已經(jīng)注入的對象丟失征字,因此報空指針異常。
解決方案
方案1:重寫JobFactory類
@Component
public class JobFactory extends SpringBeanJobFactory {
@Autowired
private AutowireCapableBeanFactory beanFactory;
/**
* 這里覆蓋了super的createJobInstance方法晴音,對其創(chuàng)建出來的類再進(jìn)行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配置文件內(nèi)配置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中直接注入bean即可
@Component
@DisallowConcurrentExecution
public class TestSuitJob implements Job {
@Autowired
private TestSuitService testSuitService;
方案2:靜態(tài)工具類
創(chuàng)建工具類SpringContextJobUtil
,實(shí)現(xiàn)ApplicationContextAware
接口,此工具類會在spring容器啟動后锤躁,自動加載搁料,使用其提供的getBean
方法獲取想要的bean即可
@Component
public class SpringContextJobUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
@SuppressWarnings("static-access" )
public void setApplicationContext(ApplicationContext contex)
throws BeansException {
// TODO Auto-generated method stub
this.context = contex;
}
public static Object getBean(String beanName){
return context.getBean(beanName);
}
public static String getMessage(String key){
return context.getMessage(key, null, Locale.getDefault());
}
}
在job內(nèi)直接調(diào)用靜態(tài)方法
testSuitService = (TestSuitService) SpringContextJobUtil.getBean("testSuitService");
以上兩種方法均可解決無法注入問題