quartz怎么注入service

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了quartz怎么注入service相关的知识,希望对你有一定的参考价值。

参考技术A 如何通过spring 向quartz动态注入service或者,传入动态参数?
这里主要用到了org.springframework.scheduling.quartz.JobDetailBean这个类的setJobDataAsMap的这个方法!
具体的API如下:
setJobDataAsMap
public void setJobDataAsMap(Map jobDataAsMap)

Register objects in the JobDataMap via a given Map.

These objects will be available to this Job only, in contrast to objects in the SchedulerContext.

Note: When using persistent Jobs whose
JobDetail will be kept in the database, do not put Spring-managed beans
or an ApplicationContext reference into the JobDataMap but rather into
the SchedulerContext.

Parameters:
jobDataAsMap - Map with String keys and any objects as values (for example Spring-managed beans)
需要注意的是红色的部分,由spring管理的Service无法通过这个方法进行注入,
spring管理的service 只能放到SchedulerContext里面。本回答被提问者采纳

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中,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);

修改后的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 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

以上是关于quartz怎么注入service的主要内容,如果未能解决你的问题,请参考以下文章

解决Spring+Quartz无法自动注入bean问题

如何在 Quartz.NET 作业中注入 NavigationManager?

使用 Quartz.NET 和 Simple Injector 进行构造函数注入

quartz的job中注入spring对象!

Spring Boot集成Quartz注入Spring管理的类

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