A依赖B,B依赖A,这样会产生循环依赖的问题。
利用三级缓存,提前暴露对象,同时解决了AOP问题。
bean的创建过程:首先实例化,然后填充属性。
实例化之后,可以把不完整的对象先暴露出来,这样就可以获取到它的引用。于是设计了一二级缓存。
以下是我理解的为何设计三级而非二级缓存的原因,欢迎指出不同意见:
但是如果实例化的对象需要AOP的话,假设还是设计为二级缓存,那么可以把代理后的对象放到二级缓存在循环依赖的时候让别人来引用。但是如果没有循环依赖的情况,会显得多此一举。而且正常的生命周期AOP处理是在初始化的最后一步进行的。于是考虑设计存的是函数式接口objectFactory,那么只有在遇到循环依赖情况的时候,才会去动态获取。但是如果有多个对象要依赖它,每次都要动态重新获取,显然违背了单例的概念,所以不得不再加一层缓存,用来保存第一次动态获取的可能动态代理的实例。
于是有了三级缓存。
一级用来保存初始化完成的完整实例;
三级用来保存objectFactory,用于获取实例;
二级用来保存三级生成的不完整实例。
以下是bean的生命周期中涉及循环依赖的步骤,方便理解:
doGetBean
getSingleton(String beanName)
优先从一级缓存取
取不到 & 创建中 (循环依赖)
二级缓存取
二级缓存取不到从三级缓存objectFactory获取到,再放入二级缓存
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
创建中
doCreateBean
如果创建中
objectFactory放入三级缓存
填充属性
创建完成
挪到一级缓存