Spring循环依赖相关问题
一、面试中常见的提问方式
1、什么是循环依赖?
2、循环依赖怎么解决?
(1)set方法进行赋值(三级缓存解决),解决循环依赖
(2)创建一个带有参数的构造方法,没有办法解决
源码BeanFactory接口中有完整的Bean周期的注释
那Spring是什么?
spring是一个框架,还是一个生态,为了支撑更加灵活高效的上层应用,对应spring而言,需要考虑最多的应该是扩展性、扩展性、扩展性
3、什么是Bean的生命周期?
AService.class—>无参构造方法—>普通对象—>依赖注入—>初始化前—>初始化—>初始化后(AOP)—>放入单例池Map—>Bean对象
这里如果没有重写构造方法,默认使用无参构造创建普通对象,可能有一些属性,包括一些加了@Autowired注解的属性,通过无参构造得到的对象里边属性都是空的
这里的依赖注入意思是就是给加了@Autowired注解的属性赋值
这里单例池Map(用的ConcurrentHashMap实现的单例Bean的功能)说的就是三级缓存中的一级缓存。//Map(beanName,Bean对象)
3.1、AService的bean生命周期
1.实例化
—>得到AService的普通对象—>KMap<beanName,AService的普通对象>
2.给bService赋值
------------>去单例池看bService在不------->没找到,创建BService
就会触发BService的生命周期
- 2.1.实例化
- 2.2.给aService赋值---->单例池—>没找到去KMap找—>AService的普通对象
- 2.3.填充其他属性
- 2.4.其他步骤(包括AOP)
- 2.5.加入到单例池
3.填充其他属性
4.其他步骤(包括AOP)
– >如果需要AOP,会产生AService代理对象
5.加入到单例池中
第一级缓存
单例池 Map<String,Object> singletonObjects
第二级缓存
Map<String,Object> earySingletonObjects
第三级缓存
Map<String,ObjectFactory<?>> singletonFactories
3.2没有找到bService怎么不给它,赋空默认值呢?
其实这里跟依赖注入有关,@Autowired点进去,required 默认true,就是说必须要有值不能为空。
AServiceProxy对象—>(通过AServiceProxy的构造方法得到)AService代理对象—>AService代理对象.target=AService普通对象
AService代理对象.test()
AService普通对象赋值给AService代理对象的target属性
class AServiceProxy extends AService{AService target;public void test(){//先切面逻辑target.test();//再执行AService普通对象.test()方法}
}
4、spring为什么要使用三级缓存来解决循环依赖问题?二级缓存能不能解决?
二级缓存虽然解决了死循环创建,但是它没有办法解决AOP代理的问题