quartz整合spring框架service层对象注入为null解决方案

Job实现类代码

 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

业务实现类代码

 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.xml

 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对象会无法注入,会报空指针异常。

原因:因为JobDetailFactoryBean中注入的是一个cn.itcast.quartz.HelloJob实现类的全路径,底层会反射创建出一个HelloJob的对象,但是该对象不是由spring管理的,所以业务层的对象无法注入。

解决方案有如下两种

方案一:将如下类JobFactory复制放到自己项目下,然后修改配置文件,并将该JobFactory配置到applicationContext.xml中(详见配置文件第20行和第22行),helloServiceImpl就能够被注入了。

 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)

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
原文地址:https://www.cnblogs.com/gongchengshixiaobai/p/7868125.html