Spring的循环依赖也是面试中的常见问题,有哪些解决方式,当面试遇到了,应该从哪几个方面开始探讨呢?
循环依赖可以从以下方面探讨:
1. 循环依赖是什么?
2. 什么情况下的循环依赖可以被解决
3. Spring是如何解决循环依赖的
循环依赖是什么
循环依赖就是两个bean对象。A和B,A中的属性有B,B中的属性有A。这样spring创建bean的过程中。。。可以自行回忆一下实例化-属性填充-初始化-销毁这个过程
什么情况下的循环依赖可以被解决
spring在解决循环依赖有两个前提:
- bean都是单例的
- DI不能全是构造器方式注入
能被解决的情况:
A,B中均采用Setter方式注入,A中采用Setter注入B,B注入A采用构造器
Spring是如何解决循环依赖的呢?
- 简单的循环依赖
- 带AOP的循环依赖
Spring是通过三级缓存来解决循环依赖的:
SingletonObjects:单例池,存放所有已经创建好的单例bean
earlySingletonObjects: 早期曝光对象,存放的是实例化,但未注入属性的bean对象
SingletonFactories: 单例工厂,二级缓存中的对象就是从这个对象中获得的
A和B创建过程的分析
spring创建对象的时候,是按照顺序来的,A在B的前面,所以先创建A
调用getBean()方法:首先创建一个新的对象,或是从缓存中获取已经存在的对象
若不存在:调用getSingleton(beanName,singletonFatctory);会把实例化后属性注入之前,把bean生成一个工厂装入三级缓存,在完成A的创建时会把A对象装入单例池。
那在对A进行属性填充的时候,使用到了B,这是会调用getBean创建B对象。B进行setter属性填充的时候遇到A,此时会调用getBean方法,那此时是从三级缓存中获取的A,填充给B,b完成初始化,然后A完成初始化.
结合了AOP的方法:B注入A的时候,注入的是A的代理对象