高频面试题:Spring 如何解决循环依赖?
2023-09-14 09:15:25 时间
Spring整个解决循环依赖问题的实现思路如下图代码。对于整体过程,需要理解两点:
- Spring是通过递归的方式获取目标bean及其所依赖的bean的;
- Spring实例化一个bean的时候,是分两步进行的,首先实例化目标bean,然后为其注入属性。
结合这两点,也就是说,Spring在实例化一个bean的时候,是首先递归的实例化其所依赖的所有bean,直到某个bean没有依赖其他bean,此时就会将该实例返回,然后反递归的将获取到的bean设置为各个上层bean的属性的。
代码:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// 实例化当前尝试获取的bean对象,比如A对象和B对象都是在这里实例化的
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 判断Spring是否配置了支持提前暴露目标bean,也就是是否支持提前暴露半成品的bean
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences
&& isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 如果支持,这里就会将当前生成的半成品的bean放到singletonFactories中,这个singletonFactories
// 就是前面第一个getSingleton()方法中所使用到的singletonFactories属性,也就是说,这里就是
// 封装半成品的bean的地方。而这里的getEarlyBeanReference()本质上是直接将放入的第三个参数,也就是
// 目标bean直接返回
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
try {
// 在初始化实例之后,这里就是判断当前bean是否依赖了其他的bean,如果依赖了,
// 就会递归的调用getBean()方法尝试获取目标bean
populateBean(beanName, mbd, instanceWrapper);
} catch (Throwable ex) {
// 省略...
}
return exposedObject;
}
End
参考:
来源: https://my.oschina.net/zhangxuf
相关文章
- 深入理解 Spring 事务:入门、使用、原理
- springboot启动原理 通俗面试_spring高级面试题
- spring boot自动配置原理面试题_Spring boot面试
- 一文教你,Spring中BeanFactory和FactoryBean的区别?
- Spring MVC各组件近距离接触--上--02
- Spring 全家桶之 Spring Boot 2.6.4(四)- Data Access(Part B MyBatis)
- 提升 Spring Boot 吞吐量的 7 个神技,让你的项目飞起来!
- Spring batch教程 之 spring batch简介
- 史上最全69道Spring面试题和答案
- Spring MVC面试题(2020最新版)[通俗易懂]
- 面试题springboot启动流程_Spring boot面试
- Spring系列69 道面试题
- spring cloud面试题_javaspring面试题
- 面试题:Spring 事务的实现方式和实现原理?
- 面试题:Spring 有什么优点
- 【Spring源码】- 08 扩展点之mybatis集成
- 只会用 Spring Boot 创建微服务?这 4 种替代方案了解一下!
- Spring Cloud Sleuth和ELK实现日志跟踪
- Spring boot+redis实现消息发布与订阅的代码
- Spring Bean继承
- spring cloud开发、部署注意详解编程语言
- Spring 5 新特性:函数式Web框架详解编程语言
- 吐血整理 20 道 Spring Boot 面试题,我经常拿来面试别人!详解编程语言
- Spring Boot 2 (二):Spring Boot 2 动态 Banner详解编程语言
- Spring Boot(十三):spring boot小技巧详解编程语言
- spring boot 发布 jar 包转为 war详解编程语言
- spring使用Spring整合Redis和Jedis构建高性能应用(redisjedis与)
- Nacos 2.0的Spring Boot Starter来了!