spring中bean的注入方式 & 循环依赖
程序员文章站
2022-03-23 22:20:16
bean的注入方式有三种:注解方式注入,一般使用@Autowired、@Resource注解。构造器注入方式如下: setter方法注入...
bean的注入方式有三种:
1. 注解方式注入,一般使用@Autowired、@Resource注解。
2. 构造器注入方式如下:
配置文件:
<bean id="a" class="org.example.constructor.A">
<constructor-arg ref="b"/>
</bean>
<bean id="b" class="org.example.constructor.B"/>
实体bean:
public class A {
public A(B b) {
}
}
3. setter方法注入如下:
配置文件:
<bean id="person" class="org.example.CircularReferences.bean.Person" scope="prototype">
<property name="customer" ref="customer"></property>
</bean>
实体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的加载流程图如下:
跟踪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