Job中无法注入Bean

环境

  • SpringBoot 2.6.4
  • Quartz 2.3.2

现象

在JOB对象中,使用@Autowire注解注入spring的bean对象,抛出空指针异常;

源码分析

scheduler使用SchedulerFactoryBean对象获取,获取方式是

Scheduler scheduler = schedulerFactoryBean.getScheduler();

因为springBoot集成了spring-boot-starter-quartz,因此可以在QuartzAutoConfiguration配置类中找到SchedulerFactoryBean的定义,如下所示:

@Bean @ConditionalOnMissingBean public SchedulerFactoryBean quartzScheduler(QuartzProperties properties, ObjectProvider<SchedulerFactoryBeanCustomizer> customizers, ObjectProvider<JobDetail> jobDetails, Map<String, Calendar> calendars, ObjectProvider<Trigger> triggers, ApplicationContext applicationContext) { SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean(); SpringBeanJobFactory jobFactory = new SpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); schedulerFactoryBean.setJobFactory(jobFactory); //省略其他代码 return schedulerFactoryBean; }

通过上述代码可以看到SchedulerFactoryBean设置类工厂类SpringBeanJobFactory,进入该类可以看到该类继承了AdaptableJobFactory类,并且实现了ApplicationContextAware接口,查看该类的创建job实例的方法,如下所示:

protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception { Object job = this.applicationContext != null ? this.applicationContext.getAutowireCapableBeanFactory().createBean(bundle.getJobDetail().getJobClass(), 3, false) : super.createJobInstance(bundle); if (this.isEligibleForPropertyPopulation(job)) { //省略其他代码 } return job; }

该方法中通过applicationContext获取到AutoWireCapableBeanFactory,进而去创建bean,也即将创建的JOB对象同时注入到spring容器中,那么也就是说在该版本的springboort中,默认情况下在JOB中注入bean是可以实现的。

不能注入原因

按照上面的分析,默认情况下,在job中注入bean是可以正常使用的,那么为什么还是出现了NullPonterException呢?原因在于项目中因为要设置Quarz的数据源,重新定义了SchedulerFactoryBean,原始代码如下:

@Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); return factory; }

这就覆盖了QuartzAutoConfiguration配置中的原始定义,此时的JOB是没有交给spring容器管理的,也就导致了注入其他bean时会出现空指针;

解决方案

在重写的配置类中,添加SpringBeanJobFactory对象,如下所示:

@Bean public SchedulerFactoryBean schedulerFactoryBean() throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setDataSource(dataSource); //关键代码 SpringBeanJobFactory jobFactory = new SpringBeanJobFactory(); jobFactory.setApplicationContext(applicationContext); factory.setJobFactory(jobFactory); //关键代码 return factory; }

__EOF__

本文作者一步一年
本文链接https://www.cnblogs.com/ybyn/p/16300670.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:编写不易,转载请注明出处
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   一步一年  阅读(209)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示