spring处理对象相互依赖注入的问题

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w1lgy/article/details/81086171 最近重新再看spri...
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w1lgy/article/details/81086171

最近重新再看spring的内容的时候有个疑问:当spring对象对象存在相互依赖注入的时候,会不会造成死循环,如果不会spring是怎么解决的?带着这个疑问我自己在eclipse试了一下,发现是能正常运行的,那么spring是怎么做到的呢,带着疑问我百度了一下,查到一篇博客可供大家参考:https://blog.csdn.net/u012410733/article/details/61062858。但是这篇博客并不能完全解决的疑问,于是我又把问题发给了线上培训的导师和培训的会员群上,经过老师的解读加上我查阅资料,做出以下总结:

一、Spring 循环依赖需要满足三个条件:

1、setter 注入(构造器注入不能循环依赖)
2、singleton bean(非单例 bean 不支持)
3、AbstractAutowireCapableBeanFactory#allowCircularReferences 这个 boolean 属性控制是否可以循环,默认为 true。

二、Spring 创建对象分为三个过程:

1、创建对象实例 Object obj = new Object() 或者 Object obj = new Object(xxx);
AbstractAutowireCapableBeanFactory#createBeanInstance
2、依赖注入: obj.setXxx(xxx) {多个属性就是 foreach}
AbstractAutowireCapableBeanFactory#populateBean
3、Spring bean 扩展方法:init-method,BeanPostProcess,XXXAware 扩展
AbstractAutowireCapableBeanFactory#initializeBean
这里写图片描述
实现原理:
这里写图片描述

我们知道在循环依赖当中其实就是多个 bean 调用 BeanFactory#getBean
具体实现在 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
而这个方在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 方法前。
首先来看一下 AbstractBeanFactory#doGetBean
这里写图片描述
在进入 doGetBean 方法时就会从缓存里面拿 beanName 对应的对象。
这里写图片描述
其实中就包含创建的 ObjectFactory

总结

相互依赖:A 依赖 B, B 依赖 A
当 A 创建的时候,会把 A 对应的 ObjectFactory 放在缓存中,当依赖注入的时候发现了 B 对象,调用 getBean() 方法获取 B 对象, 然后创建 B 对象,会把 B 对应的 ObjectFactory 放在缓存中。
此时 B 依赖 A ,然后再调用 getBean 获取 A 对象, 此时调用 AbstractBeanFactory#doGetBean 从缓存中获取到 A 对应的 ObjectFactory。
这样就避免了死循环,然后再创建成功之后删除 ObjectFactory 完成依赖注入。
思路:中间对象去解决循环依赖。

目录
相关文章
|
4月前
|
XML Java 测试技术
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
这篇文章介绍了Spring5框架的三个新特性:支持@Nullable注解以明确方法返回、参数和属性值可以为空;引入函数式风格的GenericApplicationContext进行对象注册和管理;以及如何整合JUnit5进行单元测试,同时讨论了JUnit4与JUnit5的整合方法,并提出了关于配置文件加载的疑问。
Spring5入门到实战------17、Spring5新功能 --Nullable注解和函数式注册对象。整合JUnit5单元测试框架
|
5天前
|
Java 数据库 数据安全/隐私保护
轻松掌握Spring依赖注入:打造你的登录验证系统
本文以轻松活泼的风格,带领读者走进Spring框架中的依赖注入和登录验证的世界。通过详细的步骤和代码示例,我们从DAO层的创建到Service层的实现,再到Spring配置文件的编写,最后通过测试类验证功能,一步步构建了一个简单的登录验证系统。文章不仅提供了实用的技术指导,还以口语化和生动的语言,让学习变得不再枯燥。
18 2
|
1天前
|
XML 安全 Java
Spring Boot中使用MapStruct进行对象映射
本文介绍如何在Spring Boot项目中使用MapStruct进行对象映射,探讨其性能高效、类型安全及易于集成等优势,并详细说明添加MapStruct依赖的步骤。
|
5月前
|
XML Java 测试技术
Spring Boot中的依赖注入和控制反转
Spring Boot中的依赖注入和控制反转
|
2月前
|
Java Spring
获取spring工厂中bean对象的两种方式
获取spring工厂中bean对象的两种方式
46 1
|
2月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
124 2
|
2月前
|
存储 Java 程序员
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
本文详细讲解了Spring框架中IOC容器如何存储和取出Bean对象,包括五大类注解(@Controller、@Service、@Repository、@Component、@Configuration)和方法注解@Bean的用法,以及DI(依赖注入)的三种注入方式:属性注入、构造方法注入和Setter注入,并分析了它们的优缺点。
39 0
SpringIOC和DI的代码实现,Spring如何存取对象?@Controller、@Service、@Repository、@Component、@Configuration、@Bean DI详解
|
4月前
|
Java Spring 容器
彻底改变你的编程人生!揭秘 Spring 框架依赖注入的神奇魔力,让你的代码瞬间焕然一新!
【8月更文挑战第31天】本文介绍 Spring 框架中的依赖注入(DI),一种降低代码耦合度的设计模式。通过 Spring 的 DI 容器,开发者可专注业务逻辑而非依赖管理。文中详细解释了 DI 的基本概念及其实现方式,如构造器注入、字段注入与 setter 方法注入,并提供示例说明如何在实际项目中应用这些技术。通过 Spring 的 @Configuration 和 @Bean 注解,可轻松定义与管理应用中的组件及其依赖关系,实现更简洁、易维护的代码结构。
56 0
|
4月前
|
设计模式 自然语言处理 Java
简单了解下Spring中的各种Aware接口实现依赖注入
在Spring框架中,Aware接口是一组用于提供特定资源或环境信息的回调接口。这些接口被设计用来允许Bean获取对Spring容器或其他相关资源的引用,并在需要时进行适当的处理。
43 2
|
4月前
|
安全 Java C#
Spring创建的单例对象,存在线程安全问题吗?
Spring框架提供了多种Bean作用域,包括单例(Singleton)、原型(Prototype)、请求(Request)、会话(Session)、全局会话(GlobalSession)等。单例是默认作用域,保证每个Spring容器中只有一个Bean实例;原型作用域则每次请求都会创建一个新的Bean实例;请求和会话作用域分别与HTTP请求和会话绑定,在Web应用中有效。 单例Bean在多线程环境中可能面临线程安全问题,Spring容器虽然确保Bean的创建过程是线程安全的,但Bean的使用安全性需开发者自行保证。保持Bean无状态是最简单的线程安全策略;