【工作技术栈】【源码解读】一次springboot注入bean失败问题的排查过程

前言

对这次的过程排查如果要形容的话,我觉得更像是悬疑剧,bean not found 这种错误,已经看腻了,甚至有时候都看不起这种错误,但是似乎这个想法被springboot听见了,所以这几天他就给我来了一记大耳刮子。。。

现象

版本(抛开版本就是耍流氓~)
jdk8
sprintboot 2.3.12

现象
首先我们的项目存在一个名叫common的项目,另一个叫fusionXXX的微服务依赖了这个common的项目,并且common中存在一个beandefination注册的过程(具体可以参考mybatis的mapper),因为要实现动态代理。
ok,当前idea同时打开了common项目和fusionXXX的项目,并且在一个window下,无需install到maven本地就可以直接运行,运行成功没有任何问题。

但是,现在我们将common项目install进了自己的maven仓库之后,用idea直接打开fusionXXX项目,这个时候开始运行fusionXXX项目,使用@Autowire来获取我们自己的bean,结果发现bean注入不进来,报错 bean not found

这是什么原因???

分析原因

因为二合一的项目确实可以运行,所以我认为代码没有问题,一定是springboot出了问题!具体来说应该是我使用springboot出了问题,这个分析方向对最终问题的排查起到了关键性的作用。

没啥好说的,直接开debug模式找到bean not found的堆栈处,自己去logback.xml或者log4j.xml 文件中设置日志级别,设置之后springboot会将初始化的过程打印出来,报错之后会直接打印堆栈日志,这样直接就可以点进来看了,我这边直接运行二合一和单fusionXXX来比较哪里出现了不一致导致了bean没有注入,最终定位到这里两个项目出现了不一致的问题!

在这里插入图片描述
因为是Autowire注解,该注解先通过Type来获取bean,获取不到之后再使用name的方式获取bean,二合一在这里返回的String[] 存在一个bean的名称就是我给自己的bean起的名字,但是单fusionXXX就没有,所以我们继续看503行,因为cache刚开始是没有值的,与此同时我们也了解到springboot的bean查找存在一层缓存(不虚此行!)

在这里插入图片描述

这里我们看到如果type匹配到了才会添加这个beanName(这里的beanName是循环的临时变量,这里使用了循环的方式进行type的匹配,循环的就是spring实例化bean前的beanDefination列表,只有spring第一次实例化bean的情况才会这样循环,目前我们代码中有1222个定义,所以启动起来最耗费时间的应该就是这个过程了。),二合一的536行已经匹配到了,但是fusionXXX没有匹配到那么我么继续追踪下去。
在这里插入图片描述

通过层层的比对,最终发现不一致的地方在348行,单fusionXXX在这里直接进入了349行,我们看下最终返回false的条件为什么是false
在这里插入图片描述
终于到了重要的地方,这里我们发现单fusionXXX的两个Class不是一个对象,但是二合一的都是一个对象

在这里插入图片描述
在这里插入图片描述
上面两个图如果不注意正常来讲ClassName都是一样的,但是确实无法相互赋值,为什么呢?ClassLoader不一样。。。这种真的很难排查。。。那么现在分析一下为什么不一样

首先,如果两个类的ClassLoader不一样,那么jvm会认为两个类不是同一个类,即使两个类的reference一模一样,就如上面所看

ChatGPT说RestartClassLoader是springboot中的devtools的一个类加载器,其功能是为了热加载类文件设计的,当二合一运行时,在idea中,除了jar包以外的所有class都是可编辑的,所以他们都统一被RestartClassLoader加载,因此在二合一中的两个类的加载器都是RestartClassLoader
如果不是二合一,也就是单fusionXXX的时候,common模块以jar包形式进来,在beandefination加载的时候,jar包中的类提前手动(我自己写的)被java中的应用加载器加载(AppClassLoader ,java经典三层类加载器 :bootstrap -> ext->app),而在运行过程中,比对前spring确实找到了对应的类,但是却使用了devtools中的classloader进行了加载,从而导致了在匹配Type的时候无法匹配而最终找不到bean。

被restartclassloader加载的类可以在class文件修改的时候重新加载从而起到热修改的作用。

解决方法

将devtools注释掉即可,所有类都通过java的appclassloader加载就好了,但是不支持热修改了
在这里插入图片描述

思考感悟

这次的排查使用了不少的时间才排查到,一个很常见的错误本以为很快就能解决,没想到下面藏了一个冰山。。。
整个项目仅仅在本地运行不起来,打包成功后都能够运行,总的来说不会影响到业务,但是后面引入jar包的时候也应该对jar有一定的了解。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
【资源说明】 1、该资源包括项目的全部源码,下载可以直接使用! 2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Springboot核酸检查统计系统源码.zip 基于Sprin
【资源说明】 1、基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 2、该资源包括项目的全部源码,下载可以直接使用! 3、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 4、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip 基于SpringBoot+Mybatis+Vue的一个在线选课系统源码+数据库.zip

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

元空间

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值