Qaurtz报错:org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named‘xx‘available

目录

NoSuchBeanDefinitionException报错解决

NoSuchBeanDefinitionException报错原因分析

1.容器未实例化指定类

2.Qaurtz前台页面,bean名称配置错误

3.Qaurtz框架在非集群环境下,使用同一个数据库,部署了多个版本的代码(重点)

结语


NoSuchBeanDefinitionException报错解决

关于Qaurtz定时框架的运行原理,在文章《Qaurtz定时框架,是怎么运行的(源码讲解)》中有详细讲解,自以为对Qaurtz框架的核心功能有了一个全面的了解,谁知在具体做项目的过程中,还是会遇到一些莫名其妙的问题。

首先申明,关于NoSuchBeanDefinitionException的报错的原因其实很简单:就是在Spring框架的Ioc容器中没有我们需要的bean实例。通常我们是根据bean的name去Ioc容器获取其bean实例的:

@Component("updateEmployeeInfoTask")
public class UpdateEmployeeInfoTask implements ITask {
...

比如上图这个段伪代码就是通过@Component注解,把类加载到Ioc容器中,在项目运行成功以后,我们可以通过Spring容器中的ApplicationContext的getBean方法来获取UpdateEmployeeInfoTask类的实例,其在Ioc容器中的id就是其类名的首字母小写,也就是updateEmployeeInfoTask ,但是由于我们使用了@Component的value,所以我们可以在注解后面自定义我们在Ioc容器中的id名,当然这里我们填的和默认的id保持一致,也可以自定义。

NoSuchBeanDefinitionException报错原因分析

以UpdateEmployeeInfoTask类举例分析,关于NoSuchBeanDefinitionException的报错原因, 也就是在容器中找不到这个实例,其原因有如下几点:

1.容器未实例化指定类

比如忘记写@Component注解或者类似的注解,导致类未加入Ioc容器,还有可能是写了注解,但是包和Springboot启动类不在同一个根目录下,还有可能在配置注解中把当前类的包给排除扫描了。当然,这一类情况是最简单的,我们不过多描述,大家可自行排查。

2.Qaurtz前台页面,bean名称配置错误

Qaurtz框架当然离不开前台页面,由于笔者采用的是根据bean的id来获取需要运行的定时任务实例,如果配置了一个原本不存在bean的id,也会导致出现NoSuchBeanDefinitionException报错。

 以上图为例,本来是要配置成updateEmployeeInfoTask,结果写错了配置成了updateEmployeeInfoTaskxx,也会出现报错。

3.Qaurtz框架在非集群环境下,使用同一个数据库,部署了多个版本的代码(重点)

关于前面2种情况,都是最基础的,这一种情况才是笔者真实遇到的情况。

在分析问题之前,我们先介绍一下项目背景,只有这样大家才能对整件事情有一个完整的了解。

事情的起因是由于一个公司的孵化项目,使用了Qaurtz定时框架,由于不同的使用场景,部署了2个版本,且分别部署在2台服务器,但是却使用了同一个数据库

理论上来说,如果Qaurtz框架没有使用集群部署的情况下,是不能多个项目使用同一个数据库的,因为Qaurtz框架的核心原理便是应用服务器有一个后台线程,在项目启动之后,每隔一段时间就对数据库的Qaurtz后台表进行扫描,当获取到满足条件的定时任务时,便执行任务。

在集群环境下,即使部署多个应用服务也是不影响的,但是我们采用了非集群形式,至于原因,我们在另一篇文章有提到。

问题的关键在于采用了非集群的部署方式,且2台应用服务器部署的代码版本不一样,简单来说就是第一台服务器版本为v0,第二台服务器版本为v1,v1包含v0版本的代码,但是v0不包含v1部分代码,我们假设v1在v0的基础上新建了一个testTask。

这时候v0服务器的Qaurtz后台线程在扫描数据库表的时候,可能就会扫描到v1新建的定时任务testTask,但是v0的Ioc容器钟,肯定是找不到这个bean的。

于是就会出现两个很奇怪的现象:明明v1部署了最新的代码,执行定时任务的时候,有时候可以执行成功,有时候又会执行失败;还有一个现象是,有时候定时任务的logger日志都不会打印。

当没有意识到v0还部署着一套应用的时候,笔者都对自己的Java世界观产生了动摇:spring的Ioc容器种获取同一个bean实例,怎么会时有时无?logger.info级别的日志为什么也会时有时无的打印?而且本地调试明明运行的很好,只要部署到服务器就不行了。

关键是自己反复的检查代码,也没发现哪里有问题。

是自己对Spring框架哪里理解不到位,还是说代码哪里写错了?经过无数次的尝试,始终是不得门而入。

等到休息了一晚上,第二天去网上搜了一下,看到了类似的情况,才想起来是不是多套代码对应了一个数据库。

结语

关于v0、v1版本的问题,其实无论是源码分析还是功能分析,自己都弄的比较清楚了,但是在实际的工程实践中还是会出现各种各样的问题,只能说学无止境,问题无止境。

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值