网站建设 岗位,保健品网站建设案例,企业所得税税率是多少2024年,wordpress 主查询在Spring Boot#xff08;以及Spring框架#xff09;中#xff0c;循环依赖是指两个或多个Bean互相依赖#xff0c;导致Spring在创建这些Bean时无法正常进行依赖注入。例如#xff0c;假设有两个类A和B#xff0c;A依赖于B#xff0c;而B又依赖于A。在这种情况下#x…在Spring Boot以及Spring框架中循环依赖是指两个或多个Bean互相依赖导致Spring在创建这些Bean时无法正常进行依赖注入。例如假设有两个类A和BA依赖于B而B又依赖于A。在这种情况下Spring框架在尝试实例化其中一个Bean时会发现另一个Bean尚未创建从而产生循环依赖问题。
循环依赖的类型
循环依赖可以分为构造器循环依赖和属性循环依赖两种
构造器循环依赖
当两个或多个Bean通过构造器参数相互依赖时就会出现构造器循环依赖。这种依赖情况是Spring无法处理的因为在构造器注入阶段Spring必须一次性完成所有Bean的实例化因此无法解决构造器的循环依赖。
属性循环依赖Setter循环依赖
当Bean通过属性注入Setter注入方式相互依赖时Spring可以通过创建Bean的半成品只创建实例但不完全初始化来解决这个问题。具体来说Spring首先会实例化一个Bean不调用其依赖的Setter方法然后实例化另一个Bean最后将依赖的属性注入回去。
Spring 如何处理循环依赖
单例BeanSingleton Scope
Spring默认是允许单例Bean的属性循环依赖的。它的解决机制是Spring在创建Bean时会先创建Bean的一个未完成的实例放入一级缓存即创建对象但不完全初始化还没有设置属性。然后它会将这个未初始化的对象放入一个三级缓存供后续可能需要的依赖查找使用。如果在实例化其他Bean时需要依赖这个BeanSpring会通过三级缓存获取未完成的实例并继续完成注入过程。
构造器注入
Spring无法处理构造器的循环依赖因为在构造器注入时Bean必须在构造函数中完全初始化。由于无法在构造函数执行之前就创建依赖对象Spring在这种情况下会抛出BeanCurrentlyInCreationException。
非单例BeanPrototype Scope
Spring无法解决非单例Bean的循环依赖。在Prototype作用域下Spring不管理Bean的生命周期因此无法像单例Bean一样进行缓存处理。此时如果出现循环依赖会抛出异常。
解决循环依赖的方法
重构代码消除循环依赖这是最根本的解决方式。检查是否有设计上的问题导致了循环依赖尽量将依赖解耦。可以通过引入中介类、事件机制或者工厂模式等方式重构代码。
使用Setter注入如果循环依赖无法避免可以尽量使用Setter注入而不是构造器注入因为Spring能够处理属性级别的循环依赖。
使用Lazy注解对于某些Bean依赖可以使用Lazy注解告诉Spring在需要时才初始化该Bean从而打破循环依赖。例如
Service
public class A {private final B b;Autowiredpublic A(Lazy B b) {this.b b;}
}使用ApplicationContextAware如果需要通过构造器注入的方式解决循环依赖可以通过实现ApplicationContextAware接口在运行时手动获取依赖Bean。