Spring 循环依赖解析(上)

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: Spring 现在其实是我们 Java 程序开发离不开的基础框架,个人觉得除了 JDK 我们用得最多的 Java 中间件就是 Spring ,今天我们一起来学习一下 Spring 的循环依赖。

常见问题


  • 你解释一下 spring 中的三级缓存?


  • 三级缓存分别是什么?三个 Map 有什么异同?


  • 什么是循环依赖?请谈谈?你看过 spring 的源码吗?一般我们说的是 spring  容器是什么?


  • 多例的情况下,循环依赖问题为什么无法解决?


什么是循环依赖?


多个 bean 之间相互依赖,形成闭环。 比如:A 依赖于 B, B 依赖于 C , C 依赖于 A示例代码


public class T1 {
  class A {
    B b;
  }
  class B {
    C c;
  }
  class C {
    A a; 
  }
}


比如:A 依赖于 B, B 依赖于 C , C 依赖于 A


通常来说,如果问 Spring 容器内部如何解决循环依赖,一定是指默认的单例 Bean 中, 属性相互引用的场景。


@Component
public class A {
    @Autowired
  private B b;
}
@Component
public class B {
    @Autowired
  private C c;
}
@Component
public class C {
    @Autowired
  private A a;
}


循环依赖说明


官方说明


参考官方说,下面会有官网链接


image.png


官网链接:docs.spring.io/spring-fram…


结论


构造方法注入:不支持循环依赖。结论:我们 AB 循环依赖问题。只要 A 的方式是 setter 且 singleton 就不会有循环依赖问题。


BeanCurrentlyInCreationException


循环依赖异常的定义如下所示,如果出现循环依赖,我们在启动/运行过程中会报这个错误。


image.png


依赖注入的两种方式


方式一:构造器方式注入依赖


@Component
public class ServiceA{
    private ServiceB serviceB;
    public ServiceA(ServiceB serverB) {
       this.serivceB = serviceB;
    }     
}
@Component
public class ServiceB{
    private ServiceA serviceA;
    public ServiceB(ServiceA serviceA) {
       this.serviceA = serviceA;
    }     
}


构造器循环依赖是无法解决的,你想让构造器注入支持循环依赖,是不可能的。


方式二:以 set 方式注入依赖


@Component
public class ServiceA{
    private ServiceB serviceB;
    public setServiceB(ServiceB serverB) {
       this.serivceB = serviceB;
    }     
}
@Component
public class ServiceB{
    private ServiceA serviceA;
    public setServiceB(ServiceA serviceA) {
       this.serviceA = serviceA;
    }     
}


案例演示(基于 Spring 容器的循环依赖)


普通的 Java 基础编码A  类、B 类


@Data
public class A{
  private B b;
  public A() {
     System.out.println("----- A create success");
  }
}
@Data
public class B{
  private a a;
  public B() {
     System.out.println("------ B create success");
  }    
}


循环依赖解决


A a = new A();
B b = new B();
a.setB(b);
b.setA(a);


基于 Spring 容器的循环依赖


  • 默认的单例(singleton)的场景是支持循环依赖的,不报错


  • 原型(prototype)的场景是不支持循环依赖的, 会报错


代码演示


  • 循环依赖代码


@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class A {
    @Autowired
    private B b;
}
@Component
public class B {
    @Autowired
    private A a;
}


  • 默认单例,修改为原型


// 增加注解
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)


  • 一段测试程序


class BTest {
    @Configuration
    @Import({A.class, B.class})
    public static class TestConfig {
    }
    @Test
    public void currentlyincreation() {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(TestConfig.class);
        // 这里要获取 bean 一下,如果不去主动获取,可能是由于惰性加载没有执行,不会报错
        A a = applicationContext.getBean(A.class);
        System.out.println(a);
    }
}


  • 循环依赖异常


image.png


相关文章
|
9天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
33 2
|
27天前
|
搜索推荐 Java Spring
Spring Filter深度解析
【10月更文挑战第21天】Spring Filter 是 Spring 框架中非常重要的一部分,它为请求处理提供了灵活的控制和扩展机制。通过合理配置和使用 Filter,可以实现各种个性化的功能,提升应用的安全性、可靠性和性能。还可以结合具体的代码示例和实际应用案例,进一步深入探讨 Spring Filter 的具体应用和优化技巧,使对它的理解更加全面和深入。
|
9天前
|
缓存 架构师 Java
图解 Spring 循环依赖,一文吃透!
Spring 循环依赖如何解决,是大厂面试高频,本文详细解析,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
图解 Spring 循环依赖,一文吃透!
|
1月前
|
Java 测试技术 数据安全/隐私保护
📖Java零基础-while循环语句的深度解析
【10月更文挑战第6天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
30 1
|
1月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
113 5
|
1月前
|
XML Java 数据格式
Spring底层架构源码解析(二)
Spring底层架构源码解析(二)
|
1月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
70 0
|
1月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
70 0
|
1月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
57 0
|
1月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
62 0

推荐镜像

更多
下一篇
无影云桌面