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

news2024/9/24 12:29:30

目录

  • 前言
  • 现象
  • 分析原因
  • 解决方法
  • 思考感悟

前言

对这次的过程排查如果要形容的话,我觉得更像是悬疑剧,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有一定的了解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/986018.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

spring-security-源码解析+自定义拓展

1.参考文档 https://docs.spring.io/spring-security/reference/5.7/servlet/architecture.html 1.1.各种filterchain 1.1.1.SecurityFilterChain 1.1.2.springSecurityFilterChain 1.1.3.Security Filters 2.几个重要的注解 2.1.EnableXXX EnableWebMvcSecurity–deprecate…

C语言之初阶总结篇

目录 NO.1 NO.2 NO.3 NO.4 NO.5 NO.6 NO.7 NO.8 NO.9 NO.10 NO.11 NO.12.概念tips NO.13.求最小公倍数 NO.14.最大公因数 NO.15.输入读取字符串 NO.16.倒置字符串 今天是一些C语言题目,最近天气炎热,多喝水。 NO.1 下面程序执行后&am…

浅谈泛在电力物联网、能源互联网与虚拟电厂

导读:从能源互联网推进受阻,到泛在电力物联网名噪一时,到虚拟电厂再次走向火爆,能源领域亟需更进一步的数智化发展。如今,随着新型电力系统建设推进,虚拟电厂有望迎来快速发展。除了国网和南网公司下属的电…

LLMs之Baichuan 2:《Baichuan 2: Open Large-scale Language Models》翻译与解读

LLMs之Baichuan 2:《Baichuan 2: Open Large-scale Language Models》翻译与解读 导读:2023年9月6日,百川智能重磅发布Baichuan 2。科技论文主要介绍了Baichuan 2,一个开源的大规模语言模型,以及其在多个领域的性能表现…

与 vmx86 驱动程序的版本不匹配: 预期为 410.0,实际为 401.0

与 vmx86 驱动程序的版本不匹配: 预期为 410.0,实际为 401.0。 驱动程序“vmx86.sys”的版本不正确。请尝试重新安装 VMware Workstation。 我电脑历史上装过几个版本的vmware workstation: 怀疑是不兼容版本生成的vmx.86.sys 在系统中和该软件冲突,又没…

【完整代码】2023数学建模国赛C题代码--蔬菜类商品的自动定价与补货决策

C 题 蔬菜类商品的自动定价与补货决策 在生鲜商超中,一般蔬菜类商品的保鲜期都比较短,且品相随销售时间的增加而变差, 大部分品种如当日未售出,隔日就无法再售。因此,商超通常会根据各商品的历史销售和需 求情况每天进…

java+ssh+mysql智能化办公管理系统

项目介绍: 本系统为基于jspsshmysql的OA智能办公管理系统,包含管理员、领导、员工角色,功能如下: 管理员:公告信息;工作计划;公司资料;部门管理;员工管理;员…

软件测试/测试开发丨Linux进阶命令

点此获取更多相关资料 本文为霍格沃兹测试开发学社学员学习笔记分享 原文链接:https://ceshiren.com/t/topic/27139 一、Linux进阶命令学习 curljq 二、curl简介 curl 是一个发送请求数据给服务器的工具 curl支持的协议有:FTP、FTPS、HTTP、HTTP、SFTP…

深度学习推荐系统(七)NFM模型及其在Criteo数据集上的应用

深度学习推荐系统(七)NFM模型及其在Criteo数据集上的应用 1 NFM模型原理及其实现 1.1 NFM模型原理 无论是 FM,还是其改进模型FFM,归根结底是⼀个⼆阶特征交叉的模型。受组合爆炸问题的困扰,FM 几乎不可能扩展到三阶以上,这就不…

sonarqube的基本使用

操作截图 下载一个中文插件。 插件安装成功,提示需要重启sonarqube。 通过maven的命令对代码进行测试 找到maven。 修改apache-maven-3.6.1\setting.xml。 通过以下命令对当前代码进行质量检测。 检测完毕。 回到sonarqube,看到刚刚检测的结果…

【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

👨‍💻个人主页:元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏:Uni…

Nginx 学习(十)高可用中间件的配置与实现

一 Keepalived热备 1 概述 调度器出现单点故障,如何解决?Keepalived实现了高可用集群Keepalived最初是为LVS设计的,专门监控各服务器节点的状态Keepalived后来加入了VRRP功能,防止单点故障 2 运行原理 Keepalived检测每个服务器节点状…

湖南省副省长秦国文一行调研考察亚信科技

9月5日,湖南省人民政府党组成员、副省长秦国文一行到亚信科技调研考察,亚信科技高级副总裁陈武主持接待。 图:双方合影 在亚信科技创新展示中心,秦国文了解了亚信科技在5G、算力网络、人工智能、大数据等前沿领域的创新探索&…

LeetCode 865. Smallest Subtree with all the Deepest Nodes【树,DFS,BFS,哈希表】1534

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…

AVLTree模拟实现

一、常用的搜索逻辑 1、暴力搜索 O(N) 2、二分搜索 前提是有序,可以先用O(NlogN)排序一次,后续每次查找都是logN。 缺点:快排需要容器有随机访问功能,即为顺序表等。 如果不仅要搜索,还要插入删除,此时…

修复 ChatGPT 发生错误的问题

目录 ChatGPT 发生错误?请参阅如何修复连接错误! 修复 ChatGPT 发生错误的问题 基本故障排除技巧 检查 ChatGPT 的服务器状态 检查 API 限制 检查输入格式 清除浏览数据 香港DSE是什么? 台湾指考是什么? 王湘浩 生平 …

如何安装安卓(Android 7.0+)CA根证书

简介 写这个教程时,已经是2023年,现在最新的安卓系已经是Android 13 。从Android7.0以后系统不再信任用户的证书,导致我们在使用一些网络调试工具时非常不便,为了解决这个问题,本教程将教你如何一步步操作&#xff0c…

分类预测 | MATLAB实现PCA-LSTM(主成分长短期记忆神经网络)分类预测

分类预测 | MATLAB实现PCA-LSTM(主成分长短期记忆神经网络)分类预测 目录 分类预测 | MATLAB实现PCA-LSTM(主成分长短期记忆神经网络)分类预测预测效果基本介绍程序设计参考资料致谢 预测效果 基本介绍 MATLAB实现PCA-LSTM(主成分长短期记忆神经网络)分类预测。Matlab实现基于P…

Unity中Shader的屏幕坐标

文章目录 前言一、屏幕坐标1、屏幕像素的坐标2、屏幕坐标归一化 二、在Unity中获取 当前屏幕像素 和 总像素1、获取屏幕总像素,使用_ScreenParams参数2、获取当前片段上的像素怎么使用:在片元着色器传入参数时使用 前言 Unity中Shader的屏幕坐标 一、屏幕坐标 1、屏幕像素的坐…

YOLOV7改进-添加CoordConv(坐标卷积)

坐标卷积link 只替换FPN1x1卷积层和检测头中的第一卷积层 1、复制到common文件夹最后 2、做改进对比实验时,不要载入与训练权重 3、yolo.py解析模型里面 4、对yolov7.yaml的配置文件修改 5、对fpn1x1卷积替换