quartz定时任务service注入失败的详细的原因我查了查是这样的:

Job是在quartz的框架中实例化的,service是在spring容器中创建出来的,所以Job实现类不受spring管理,即导致注入失败,所以要想解决这个问题就需要,将他们关联起来。好在Quartz提供了JobFactory接口,就可以自定义实现创建Job的逻辑。就像这样:

public interface JobFactory {
    Job newJob(TriggerFiredBundle var1, Scheduler var2) throws SchedulerException;
}

这个接口所处的位置就是我们在maven引入的Quartz Jar包,是quartz包里面的一个接口,我们通过实现JobFactory接口,在实例化Job以后,在通过ApplicationContext将Job所需要的属性注入即可。

在Spring与Quartz集成时,用到的是SchedulerFactoryBean这个类,这个类是spring-context-support里面的一个类,源码里面有这么一句话(源码很长,我也不会一一解读,很多其实也看不懂,但截取了其中涉及到的一段):

this.scheduler = this.createScheduler(schedulerFactory, this.schedulerName);
this.populateSchedulerContext();
if (!this.jobFactorySet && !(this.scheduler instanceof RemoteScheduler)) {
    this.jobFactory = new AdaptableJobFactory();
}

if (this.jobFactory != null) {
    if (this.jobFactory instanceof SchedulerContextAware) {
        ((SchedulerContextAware)this.jobFactory).setSchedulerContext(this.scheduler.getContext());
    }

    this.scheduler.setJobFactory(this.jobFactory);
}

这段代码解释是这样的,如果我们不指定JobFactory,那么spring就使用AdaptableJobFactory,这个类就是JobFactory的实现类,AdaptableJobFactory的不分源码如下:

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
    Method getJobDetail = bundle.getClass().getMethod("getJobDetail");
    Object jobDetail = ReflectionUtils.invokeMethod(getJobDetail, bundle);
    Method getJobClass = jobDetail.getClass().getMethod("getJobClass");
    Class jobClass = (Class)ReflectionUtils.invokeMethod(getJobClass, jobDetail);
    return jobClass.newInstance();
}
此处创建了一个Job实例,那我们就在这里去给Job的属性进行注入就可以了,然后我们就写一个类来继承他,并重写这个方法对Job进行注入。如下:

public class MyJobFactory extends AdaptableJobFactory {
    @Autowired
    private AutowireCapableBeanFactory autowireCapableBeanFactory;

    @Override
    protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
        //调用父类的方法
        Object jobInstance = super.createJobInstance(bundle);
        //进行注入,这属于Spring的技术,不清楚的可以查看SpringAPI.
        autowireCapableBeanFactory.autowireBean(jobInstance);
        return jobInstance;
    }
}

然后把他配置到spring当中去,参考前一篇文章里面xml的配置里面的一句话。

<bean id="jobFactory" class="com.gao.ssm.module.quartz.MyJobFactory"/>

然后把SchedulerFactoryBean的JobFactory设置成我们自己的。

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    <property name="jobFactory" ref="jobFactory"/>
    <!--其他属性值省略-->
</bean>

这样就完成了Spring对Job的注入功能,原理就是在我们扩展JobFactory创建Job的方法,在创建完Job以后进行属性注入。

跟上面的分析我自己集合类所在jar包整理了一下,我觉得观察上面的类所在的jar就更容易理解,job如何自动注入spring容器托管的对象 。

【quartz】quartz定时任务service注入失败

(说明:本文是我参照另一篇文章 为加深理解自己敲了一遍,读者也可以直接读原文。)

相关文章:

  • 2021-07-09
  • 2021-10-11
  • 2022-01-06
  • 2022-01-19
猜你喜欢
  • 2021-05-17
  • 2021-07-09
  • 2021-07-28
  • 2021-04-30
  • 2021-09-29
相关资源
相似解决方案