本文主要是介绍Spring4.X+Quartz2.X无法自动注入bean问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Quartz是目前非常流行的任务框架,一般用来做定时任务。
但是在QuartzJobBean中无法使用注解自动注入bean。
需要达到的效果:
@Resourceprivate IAlumniService alumniService;
原因是因为Job对象的实例化过程是在Quartz中进行的,bean是在Spring容器当中的,那么如何将他们关联到一起呢?
Quartz提供了JobFactory接口,让我们可以自定义实现创建Job的逻辑。那么我们通过实现JobFactory 接口,在实例化Job以后,在通过ApplicationContext 将Job所需要的属性注入即可。
重写JobFactory
/*** Created by XFL.* time on 2016/10/4 23:13* description:自定义JobFactory以便在JobBean中可以获取Spring注解的bean*/
public class MyJobFactory extends AdaptableJobFactory {/*** 这个对象Spring会帮我们自动注入进来,也属于Spring技术范畴.*/private AutowireCapableBeanFactory capableBeanFactory;/*** 注入capableBeanFactory.* @param capableBeanFactory AutowireCapableBeanFactory*/@Autowiredpublic MyJobFactory(final AutowireCapableBeanFactory capableBeanFactory) {Assert.notNull(capableBeanFactory, "自动注入AutowireCapableBeanFactory失败");this.capableBeanFactory = capableBeanFactory;}/*** 重写该方法,以便在quartz中可以获取注解的bean.* @param bundle TriggerFiredBundle* @return 返回实例(Spring bean)* @throws Exception 异常*/protected final Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {//调用父类的方法Object jobInstance = super.createJobInstance(bundle);//进行注入,这属于Spring的技术,不清楚的可以查看Spring的API.capableBeanFactory.autowireBean(jobInstance);return jobInstance;}
}
Spring-quartz配置文件,这里只考虑单机部署,未考虑集群,分布式部署。如需要集群部署需要更改此文件,在bean quartzScheduler中需要加入datascore,quartz集群配置文件等等。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean name="quartzScheduler"class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="jobFactory" ref="myJobFactory"/><property name="triggers"><list><ref bean="trigger" /></list></property></bean><!--任务--><bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"><property name="jobClass" value="com.jxufe.schedule.task.QuartzTestJobBean"/><property name="durability" value="true" /><property name="requestsRecovery" value="true" /></bean><!--触发器--><bean id="trigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"><property name="jobDetail" ref="jobDetail" /><property name="cronExpression" value="0 0/5 * * * ?" /></bean><bean id="myJobFactory" class="com.jxufe.schedule.task.MyJobFactory"/>
</beans>
任务
public class QuartzTestJobBean extends QuartzJobBean {/*** Log4j2 日志对象.*/private static final Logger logger = LogManager.getLogger(QuartzTestJobBean.class);/*** 注入alumniService.*/@Resourceprivate IAlumniService alumniService;/*** 测试定时任务.* @param jobExecutionContext 定时任务* @throws JobExecutionException 抛出异常*/@Overrideprotected final void executeInternal(final JobExecutionContext jobExecutionContext) throws JobExecutionException {logger.info("执行定时任务QuartzTestJobBean");System.out.println("执行定时任务");// SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);Map<String, Object> parameterMap = new HashMap<>();//获取beanif (alumniService != null) {List<Map<String, Object>> result = alumniService.findAlumni(parameterMap);if (result != null) {logger.info("获取的大小" + result.size());}}logger.info("执行定时任务完毕QuartzTestJobBean");}
}
还有一种解决办法是在任务中加入,使用这种方法可以不需要重写JobFactory
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
注意:以上方法如果使用构造函数注入,是仍然不行的
使用到的框架包
Spring基础包,SpringMVC框架包
spring-context-support,quartz,quartz-jobs
这篇关于Spring4.X+Quartz2.X无法自动注入bean问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!