Spring 如何解决 Bean 的循环依赖(循环引用)

简介: Spring 如何解决 Bean 的循环依赖(循环引用)
@Component
public class A {
    @Autowired
    private B b;
}
@Component
public class B {
    @Autowired
    private A a;
}

上面的情况就是 循环依赖

Bean的创建初始化过程如下

如果不采取措施,那么循环依赖就会进入死循环

但 Spring 已经帮我们解决了大部分循环依赖问题

具体是如何解决的?

Spring解决循环依赖是通过三级缓存,对应的三级缓存如下所示:

缓存名称

源码名称

作用

一级缓存

singletonObjects

单例池,缓存已经经历了完整的生命周期,已经初始化完成的bean对象

二级缓存

earlySingletonObjects

缓存早期的bean对象(生命周期还没走完)

三级缓存

singletonFactories

缓存的是ObjectFactory,表示对象工厂,用来创建某个对象的

下图是Bean的生命周期,我们依照Bean的生命周期来说明,关于Bean的生命周期可以参考我的另外一篇博客

一级缓存 存放 已经全部完成的Bean,可以直接使用

二级缓存 存放 早期的bean对象,其生命周期还没走完,也就是仅通过构造函数创建出实例,但未进行依赖注入及其以下初始化步骤

三级缓存 存放 对象工厂,对象工厂用于创建对象,其具体作用下面会说明

实际上 一级 和 二级 缓存就能解决一般的 循环依赖问题


但是 如果一个对象被增强了,即 是个代理对象, 这个时候就需要一个三级缓存

但是 仍有些循环引用 Spring 解决不了,这时候需要手动解决,最典型的就是 构造方法出现了循环依赖,如下

@Component
public class A {
    // B成员变量
    private B b;
    public A(B b){
        System.out.println("A的构造方法执行了...");
        this.b = b ;
    }
}
@Component
public class B {
    // A成员变量
    private A a;
    public B(A a){
        System.out.println("B的构造方法执行了...");
        this.a = a ;
    }
}

解决办法 -- 延迟加载:

1. public A(@Lazy B b){
2.     System.out.println("A的构造方法执行了...");
3. this.b = b ;
4. }


目录
相关文章
|
6月前
|
监控 安全 Java
解决 Spring Boot 中 SecurityConfig 循环依赖问题的详解
本文详细解析了在 Spring Boot 中配置 `SecurityConfig` 时可能遇到的循环依赖问题。通过分析错误日志与代码,指出问题根源在于 `SecurityConfig` 类中不当的依赖注入方式。文章提供了多种解决方案:移除 `configureGlobal` 方法、定义 `DaoAuthenticationProvider` Bean、使用构造函数注入以及分离配置类等。此外,还讨论了 `@Lazy` 注解和允许循环引用的临时手段,并强调重构以避免循环依赖的重要性。通过合理设计 Bean 依赖关系,可确保应用稳定启动并提升代码可维护性。
482 0
|
8月前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
518 26
|
7月前
|
Java Maven 微服务
微服务——SpringBoot使用归纳——Spring Boot集成 Swagger2 展现在线接口文档——Swagger2 的 maven 依赖
在项目中使用Swagger2工具时,需导入Maven依赖。尽管官方最高版本为2.8.0,但其展示效果不够理想且稳定性欠佳。实际开发中常用2.2.2版本,因其稳定且界面友好。以下是围绕2.2.2版本的Maven依赖配置,包括`springfox-swagger2`和`springfox-swagger-ui`两个模块。
225 0
|
7月前
|
缓存 Java 应用服务中间件
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——依赖导入和Thymeleaf相关配置
在Spring Boot中使用Thymeleaf模板,需引入依赖`spring-boot-starter-thymeleaf`,并在HTML页面标签中声明`xmlns:th="http://www.thymeleaf.org"`。此外,Thymeleaf默认开启页面缓存,开发时建议关闭缓存以实时查看更新效果,配置方式为`spring.thymeleaf.cache: false`。这可避免因缓存导致页面未及时刷新的问题。
283 0
|
10月前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
186 12
|
10月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
235 12
|
10月前
|
XML Java 数据格式
Spring容器Bean之XML配置方式
通过对以上内容的掌握,开发人员可以灵活地使用Spring的XML配置方式来管理应用程序的Bean,提高代码的模块化和可维护性。
269 6
|
10月前
|
XML Java 数据格式
🌱 深入Spring的心脏:Bean配置的艺术与实践 🌟
本文深入探讨了Spring框架中Bean配置的奥秘,从基本概念到XML配置文件的使用,再到静态工厂方式实例化Bean的详细步骤,通过实际代码示例帮助读者更好地理解和应用Spring的Bean配置。希望对你的Spring开发之旅有所助益。
430 4
|
3月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
749 0
|
7月前
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
326 0