java 注入 循环_spring中bean的注入方式 & 循环依赖

本文详细剖析了Spring框架如何处理bean的循环依赖问题,通过核心类`DefaultSingletonBeanRegistry`中的机制,讲解了注解注入和setter方法注入的处理方式。重点介绍了`singletonFactories`缓存和循环依赖检测机制。实例演示了构造器依赖的循环问题及解决策略。
摘要由CSDN通过智能技术生成

bean的注入方式有三种:

1. 注解方式注入,一般使用@Autowired、@Resource注解。

2. 构造器注入方式如下:

配置文件:

实体bean:

public class A {

public A(B b) {

}

}

3. setter方法注入如下:

配置文件:

实体bean:

public class Customer {

public Person person;

public void setPerson(Person person) {

this.person = person;

}

}

spring是如何解决bean循环依赖(相互依赖)的,我们来分析核心源码:

核心容器类DefaultSingletonBeanRegistry,里面有几个比较重要的属性变量,需要着重说明一下:

1. singletonObjects 单例对象列表, beanName -> bean实例

2. singletonFactories 单例工厂列表 beanName -> beanFactory

3. earlySingletonObjects 循环对象依赖列表,对象在创建之后,进行注入过程中,发现产生了循环依赖,那么会将对象放入到这个队列,并且从singletonFactories中移除掉。

4. singletonsCurrentlyInCreation 正在创建的单例名称队列

5. registeredSingletons 已经创建成功的单例名称列表

spring只能解决上面第一种或第三种方式的循环依赖,且要求单例的bean,不能解决构造器的循环依赖。

这里举例有两个bean,A和B,循环依赖bean的加载流程图如下:

c7d924bbf9d431ee718886b587d3ab8e.png

跟踪bean的创建流程进入AbstractAutowireCapableBeanFactory类的doCreateBean()方法,核心代码:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)

throws BeanCreationException {

BeanWrapper instanceWrapper = null;

// 省略代码

if (instanceWrapper == null) {

// 实例化bean

instanceWrapper = createBeanInstance(beanName, mbd, args);

}

//判断是单例、允许循环依赖、正在创建的单例队列bean

boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&

isSingletonCurrentlyInCreation(beanName));

//提早暴露

if (earlySingletonExposure) {

// 重点!!!将实例化的对象添加到singletonFactories三级缓存中

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

}

// 初始化bean

Object exposedObject = bean;

try {

populateBean(beanName, mbd, instanceWrapper);//也很重要

exposedObject = initializeBean(beanName, exposedObject, mbd);

}

// 省略无关代码

return exposedObject;

}

拿自动注入来说,当bean A走到populateBean()方法时,会调用到AutowiredAnnotationBeanPostProcessor类中的postProcessProperties()方法,最后会调用到beanFactory.getBean(beanName)。然后bean B会被创建,bean B创建时从singletonFactories缓存中拿到A作为自己的属性依赖,然后将B赋值给A,最后A、B一起创建完毕。

本文地址:https://blog.csdn.net/qq_35261593/article/details/109966787

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值