spring为什么要用三级缓存,而不是二级缓存?
spring为什么要用三级缓存,而不是二级缓存?
可以有两种理解:
1. spring为什么要多使用第三级缓存?spring为什么不直接返回早期对象或早期代理对象到第二级缓存中? (第一级+第二级)
2. spring为什么要多使用第二级缓存?去掉第二级缓存可以吗? (第一级+第三级)
概念理解:
spring的三级缓存
1层 | singletonObjects | 第一级缓存,存放可用的成品Bean 。 |
2层 | earlySingletonObjects | 第二级缓存,存放半成品的Bean ,半成品的Bean 是已创建对象,但是未注入属性和初始化。用以解决循环依赖。 |
3层 | singletonFactories | 第三级缓存,存的是Bean工厂对象 ,用来生成半成品的Bean 并放入到二级缓存中。用以解决循环依赖。 |
问:两级缓存可以解决循环依赖吗?(只有第一级和第二级的缓存可以解决循环依赖吗)
答:如果不使用第三级缓存(指不使用工厂模式返回对象,而是直接返回一个早期对象/代理早期对象放入第二级缓存中);意味着Bean在构造完后就创建代理对象,这样违背了Spring设计原则。Spring结合AOP跟Bean的生命周期,是在Bean创建完全之后通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来完成的,在这个后置处理的postProcessAfterInitialization方法中对初始化后的Bean完成AOP代理。如果出现了循环依赖,那没有办法,只有给Bean先创建代理,但是没有出现循环依赖的情况下,设计之初就是让Bean在生命周期的最后一步完成代理而不是在实例化 后就立马完成代理。
问:可以去掉第二级缓存吗(只有第一级和第三级的缓存)
答:去掉第二级缓存会在 a依赖b,c ;bc依赖a 这样的多循环的时候 ,每次从工厂返回的早期对象/早期代理对象 不唯一,导 致b和c引用的a早期对象不是同一个
总结:1.两级缓存是可以解决循环依赖的,违反spring的设计原则;
2.去掉第二级缓存会导致可能通过工厂get出来的早期对象不一致,不能保证单例;