【问题】容器部署场景Spring Bean偶尔循环依赖问题

问题描述

在本地开发中不会发生循环依赖问题,但是在容器场景下,制作成镜像启动后异常出现Bean的循环依赖。

问题原因

开发者在代码中使用构造函数注入来引用依赖的 Bean,这种方式可能导致循环依赖问题。虽然 Spring 框架具备循环依赖的处理机制,但它仅适用于通过 @Resource 或 @Autowired 注解进行的 Setter 方法注入或字段注入。如果开发者使用构造函数注入,当Bean的初始化未发生循环依赖,则启动没问题,对应日常开发中不会有循环依赖问题,但是在一些Docker容器场景,则会偶发抛出循环依赖异常。

深入剖析原理

在这里插入图片描述

进一步深入分析为什么本地没有循环依赖问题,但是容器里或服务器里偶发会出现循环依赖问题,问题的根源在于 Spring Boot 在扫描和实例化 Bean 时的顺序并非固定,而是可能受到 Jar 包中文件列表顺序 的影响。

  1. Jar 包文件列表的顺序
  • 在 Java 中,Jar 文件实际上是一个压缩包,内部包含了许多类文件和资源文件。当应用程序运行时,可能需要遍历这些文件。例如,Spring Boot 在启动时需要扫描特定路径下的类和资源,以识别需要创建的 Bean。
  • 在 Java 中,可以使用 JarFile.entries() 方法获取 Jar 包中的所有条目。然而,需要注意的是:JarFile.entries() 返回的并非是一个稳定有序的列表。根据 Java 官方文档,entries() 返回一个 Enumeration,但并未保证返回的顺序
  • 不同的平台或工具在打包 Jar 文件时,可能导致文件列表的顺序不同。例如,在 Windows 和 Linux 上生成的 Jar 文件,即使内容完全相同,但内部文件的排列顺序可能不同。
  1. Spring Boot 的资源匹配逻辑
    Spring Boot 使用 PathMatchingResourcePatternResolver 类来处理资源的匹配和加载。其中,doFindPathMatchingJarResources() 方法负责在 Jar 文件中查找与指定模式匹配的资源。
protected Set<Resource> doFindPathMatchingJarResources(Resource rootDirResource, String subPattern) throws IOException {
   
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值