• 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
  • 相关阅读:
    提高关键词排名的28个优化技巧
    Web存储机制—sessionStorage,localStorage使用方法
    19个JavaScript简化编码小技巧
    禁止浏览器滚动条滚动,但滚动条可以显示
    H5项目常见问题及注意事项
    利用cookie实现“只弹出一次窗口”的JS代码
    关于JSON.parse在ie6,ie7下未定义的issue
    你真的会使用XMLHttpRequest吗?
    页面内容不足以铺满屏幕高度时,footer居底显示
    CSS box-shadow 属性
  • 原文地址:https://www.cnblogs.com/gongchengshixiaobai/p/7868125.html
Copyright © 2020-2023  润新知