quartz整合spring框架service層對象注入爲null解決方案

Job實現類代碼java

 1 package cn.itcast.quartz;
 2 
 3 import org.quartz.Job;
 4 import org.quartz.JobExecutionContext;
 5 import org.quartz.JobExecutionException;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.stereotype.Service;
 8 
 9 import cn.itcast.service.HelloServiceImpl;
10 
11 /**      
12  * @author: 攻城獅小白
13  * @creationTime:2017年11月20日 下午5:21:28
14  */
15 @Service
16 public class HelloJob implements Job{
17 
18     @Autowired
19     private HelloServiceImpl helloServiceImpl;
20     public void execute(JobExecutionContext context) throws JobExecutionException {
21         helloServiceImpl.sayHello();
22     }
23 
24 }
HelloJob.java

業務實現類代碼web

 1 package cn.itcast.service;
 2 
 3 import org.springframework.stereotype.Service;
 4 
 5 /**      
 6  * @author: 攻城獅小白
 7  * @creationTime:2017年11月20日 下午5:42:12
 8  */
 9 @Service
10 public class HelloServiceImpl {
11     public void sayHello(){
12         System.out.println("hello quartz...");
13     }
14 }
HelloServiceImpl.java

spring核心配置文件applicationContext.xmlspring

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="
 6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 8 
 9     <context:component-scan base-package="cn.itcast"></context:component-scan>
10     <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
11         <property name="jobClass" value="cn.itcast.quartz.HelloJob"></property>
12     </bean>
13     
14     <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
15         <property name="jobDetail" ref="jobDetail"></property>
16         <property name="startDelay" value="3000"></property>
17         <property name="repeatInterval" value="5000"></property>
18     </bean>
19     
20     <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
21         <property name="triggers">
22             <list>
23                 <ref bean="simpleTrigger"/>
24             </list>
25         </property>
26     </bean>
27 </beans>
applicationContext.xml

描述:按上面配置的代碼執行時,helloServiceImpl對象會沒法注入,會報空指針異常。app

緣由:由於JobDetailFactoryBean中注入的是一個cn.itcast.quartz.HelloJob實現類的全路徑,底層會反射建立出一個HelloJob的對象,可是該對象不是由spring管理的,因此業務層的對象沒法注入。ide

解決方案有以下兩種this

方案一:將以下類JobFactory複製放到本身項目下,而後修改配置文件,並將該JobFactory配置到applicationContext.xml中(詳見配置文件第20行和第22行),helloServiceImpl就可以被注入了。spa

 1 package cn.itcast.quartz;
 2 
 3 import org.quartz.spi.TriggerFiredBundle;
 4 import org.springframework.beans.factory.annotation.Autowired;
 5 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
 6 import org.springframework.scheduling.quartz.AdaptableJobFactory;
 7 import org.springframework.stereotype.Service;
 8 
 9 @Service("jobFactory")
10 public class JobFactory extends AdaptableJobFactory {
11     @Autowired
12     private AutowireCapableBeanFactory capableBeanFactory;
13     @Override
14     protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
15         // 調用父類的方法
16         Object jobInstance = super.createJobInstance(bundle);
17         // 進行注入
18         capableBeanFactory.autowireBean(jobInstance);
19         return jobInstance;
20     }
21 }
JobFactory.java
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="
 6         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
 8 
 9     <context:component-scan base-package="cn.itcast"></context:component-scan>
10     <bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
11         <property name="jobClass" value="cn.itcast.quartz.HelloJob"></property>
12     </bean>
13     
14     <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean">
15         <property name="jobDetail" ref="jobDetail"></property>
16         <property name="startDelay" value="3000"></property>
17         <property name="repeatInterval" value="5000"></property>
18     </bean>
19     
20     <bean id="jobFactory" class="cn.itcast.quartz.JobFactory"></bean>
21     <bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
22         <property name="jobFactory" ref="jobFactory"></property>
23         <property name="triggers">
24             <list>
25                 <ref bean="simpleTrigger"/>
26             </list>
27         </property>
28     </bean>
29 </beans>
applicationContext.xml

方案二:在Job實現類中添加下面這行代碼便可(這種方式雖然方便,可是當你的Job實現類過多時,須要給每一個類都添加該行代碼,因此當Job實現類過多的時候建議仍是採用方案一,只須要配置一次就OK)3d

SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);指針

 1 package cn.itcast.quartz;
 2 
 3 import org.quartz.Job;
 4 import org.quartz.JobExecutionContext;
 5 import org.quartz.JobExecutionException;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.stereotype.Service;
 8 import org.springframework.web.context.support.SpringBeanAutowiringSupport;
 9 
10 import cn.itcast.service.HelloServiceImpl;
11 
12 /**      
13  * @author: 攻城獅小白
14  * @creationTime:2017年11月20日 下午5:21:28
15  */
16 @Service
17 public class HelloJob implements Job{
18     @Autowired
19     private HelloServiceImpl helloServiceImpl;
20     public void execute(JobExecutionContext context) throws JobExecutionException {
21         SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
22         helloServiceImpl.sayHello();
23     }
24 }
HelloJob.java
相關文章
相關標籤/搜索