循环依赖报错那天,我们把 @Lazy 的使用圈了起来
【摘要】 SpringBoot2.6起allow-circular-references默认关闭,升级后一批老服务启动即失败。当时最快的解法显然是把开关打开,我们明令禁止——它只是把报错变成隐患,环还在,只是Spring替你绕了。先讲机制:三级缓存能解setter或字段注入的环,靠的是提前暴露一个早期引用给对方;但构造器注入的环无解(对象没构造完就没有引用可暴露),原型Bean的环同样无解。所以报错信...
Spring Boot 2.6 起 allow-circular-references 默认关闭,升级后一批老服务启动即失败。当时最快的解法显然是把开关打开,我们明令禁止——它只是把报错变成隐患,环还在,只是 Spring 替你绕了。
先讲机制:三级缓存能解 setter 或字段注入的环,靠的是提前暴露一个早期引用给对方;但构造器注入的环无解(对象没构造完就没有引用可暴露),原型 Bean 的环同样无解。所以报错信息里如果是构造器注入,别折腾配置,直接改结构。
正确的拆法两个方向:其一,提取第三方案例——A 和 B 互相调用的逻辑,多数是有一块职责放错了地方,抽成新的 C,A、B 都依赖 C,环消失,顺便让职责更干净;其二,事件化——A 不直接调 B,改发事件,B 监听,编译期没有环,代价是调用链变成运行时行为,排障要适应。
@Lazy 是受控的例外:注入的是代理,首次使用才解析依赖。适合过渡期和解燃眉之急,我们允许它的前提是代码评审里说明原因和退出时间,且每个季度扫一遍 @Lazy 的存量,防止过渡态变成永久态。
排查工具就用启动日志本身,报错里的循环路径画成依赖图,多数环一眼就能看出是哪两个类在互相越界。根治循环依赖的手段不是配置开关,是每次 code review 时对依赖方向的敏感——单向依赖的代码库,这类问题从根上就不存在。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)