博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
spring处理对象相互依赖注入的问题
阅读量:7135 次
发布时间:2019-06-28

本文共 1438 字,大约阅读时间需要 4 分钟。

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/w1lgy/article/details/81086171

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

一、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 完成依赖注入。
思路:中间对象去解决循环依赖。

你可能感兴趣的文章
python 通过threading多线程ssh
查看>>
spark-submit使用及说明
查看>>
jquery验证表单的js代码(HTML+CSS+PHP代码部分省略)
查看>>
Linux学习之CentOS(二十)--CentOS6.4下修改MySQL编码方法
查看>>
我的友情链接
查看>>
手动删除oracle数据库
查看>>
(转)chrome浏览器在各常用移动终端上的User-Agent
查看>>
向Maven本地仓库添加本地jar包
查看>>
Nginx 配置虚拟主机
查看>>
CHI Hair Straightener
查看>>
Redis测试报告
查看>>
邮件归档对安全的整合与提高
查看>>
微信小程序把玩(九)scroll-view组件
查看>>
apache目录访问权限
查看>>
spring MVC配置详解
查看>>
function
查看>>
Easy ×××
查看>>
java-插补查找法
查看>>
PHP命令行参数详解及应用
查看>>
shell脚本作业
查看>>