0

0

如何在Java中处理复杂的对象依赖关系_理解循环依赖的风险

P粉602998670

P粉602998670

发布时间:2026-02-15 09:33:10

|

818人浏览过

|

来源于php中文网

原创

spring默认禁止构造器注入的循环依赖,因无法提前暴露实例;仅支持单例bean在setter/字段注入下通过三级缓存解决,原型bean及隐式依赖(如事件监听、@postconstruct中getbean)仍会失败。

如何在java中处理复杂的对象依赖关系_理解循环依赖的风险

Spring 为什么默认禁止循环依赖

Spring 容器在单例 Bean 初始化过程中,会提前暴露一个“正在创建中”的 ObjectFactory 来应对循环依赖。但它只对「构造器注入」完全无解,仅支持「setter 或字段注入」场景下的三级缓存自救。

常见错误现象:BeanCurrentlyInCreationException 或启动时报 Requested bean is currently in creation;本质是 A 依赖 B、B 又在构造器里强依赖 A,Spring 连实例都还没 new 出来,根本没法塞进缓存。

  • 构造器注入 + 循环依赖 → 必然失败,Spring 不做任何尝试
  • 字段/Setter 注入 + 单例 + 非懒加载 → Spring 能靠 singletonObjects / earlySingletonObjects / singletonFactories 三级缓存兜住
  • 原型(@Scope("prototype"))Bean 出现循环依赖 → 直接抛异常,不走缓存逻辑

如何识别代码里藏着的隐式循环依赖

不是只有 A → B → A 才叫循环依赖。当存在继承、代理、事件监听或自动装配泛型时,依赖链可能被遮蔽。

典型场景:

立即学习Java免费学习笔记(深入)”;

  • 使用 @EventListener 订阅本类发布的事件 → 当前 Bean 尚未初始化完成,但事件机制已触发其方法调用
  • 通过 ApplicationContext.getBean(Xxx.class)@PostConstruct 中手动获取另一个 Bean,而那个 Bean 又间接依赖当前类
  • Lombok 的 @RequiredArgsConstructor 自动生成构造器,若字段类型恰好形成闭环,编译期看不出,运行时报错

建议在 IDE 中右键查看 “Find Usages” 后逆向追踪依赖图,比光看 @Autowired 更可靠。

办公人导航
办公人导航

办公人导航是一个实用的办公生活导航网站

下载

@Lazy 能不能一劳永逸解决循环依赖

@Lazy 是最常用的绕过手段,但它只是延迟初始化,并不消除依赖关系本身。

要注意:

  • @Lazy 对构造器参数生效,但必须确保该 Bean 自身也是单例(否则每次 getBean 都新建,@Lazy 失效)
  • @Async 或事务代理结合时,@Lazy 可能导致代理对象未正确织入,出现空指针或事务不生效
  • 测试环境下若用 Mockito.mock() 替换 Bean,@Lazy 会让 mock 行为失效——因为 Spring 拿到的是代理,不是原始 mock 实例

示例:如果 B 类有 @Lazy final A a;,那第一次调用 a.doSomething() 才触发 A 的创建,此时若 A 又依赖 C、C 又依赖 B,就又回到原问题。

真正该重构的不是配置,是职责边界

循环依赖往往暴露的是设计问题:两个类承担了不该耦合的职责,比如服务层直接操作数据源配置、监听器里混着业务逻辑、或者把策略选择和策略实现写死在同一处。

比起加 @Lazy 或拆成 setter,更值得花时间做的:

  • 把共享状态抽成独立的 @Service,让 A 和 B 都依赖它,而非彼此
  • ApplicationEventPublisher 替代直接调用,把“执行时机”和“执行主体”解耦
  • 对复杂流程引入命令模式或状态机,避免服务类之间形成网状调用

Spring 的循环依赖支持是个补丁,不是设计指南。它能让你跑起来,但跑得久不久,取决于你有没有动过那几行真正该删掉的依赖。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
spring框架介绍
spring框架介绍

本专题整合了spring框架相关内容,想了解更多详细内容,请阅读专题下面的文章。

134

2025.08.06

Java Spring Security 与认证授权
Java Spring Security 与认证授权

本专题系统讲解 Java Spring Security 框架在认证与授权中的应用,涵盖用户身份验证、权限控制、JWT与OAuth2实现、跨站请求伪造(CSRF)防护、会话管理与安全漏洞防范。通过实际项目案例,帮助学习者掌握如何 使用 Spring Security 实现高安全性认证与授权机制,提升 Web 应用的安全性与用户数据保护。

81

2026.01.26

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

604

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

21

2025.12.06

空指针异常处理
空指针异常处理

本专题整合了空指针异常解决方法,阅读专题下面的文章了解更多详细内容。

23

2025.11.16

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

149

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

104

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

35

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

14

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3.6万人学习

C# 教程
C# 教程

共94课时 | 9.5万人学习

Java 教程
Java 教程

共578课时 | 66.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号