Spring源码学习之 三 getBean
作用
获取Spring容器中已初始化的bean,getBean一共有以下几种方法原型:
- Object getBean(String name)
- T getBean(String name, Class requiredType)
- Object getBean(String name, Object… args)
- T getBean(Class requiredType)
- T getBean(Class requiredType, Object… args)
主要流程图和Bean后置处理器9大调用点
三级缓存
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
// 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
// 二级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
}
- 一级缓存:singletonObjects 存储的是所有创建好了的单例Bean
- 二级缓存:earlySingletonObjects 完成实例化,但是还未进行属性注入及初始化的对象
- 三级缓存:singletonFactories 提前暴露的一个单例工厂,二级缓存中存储的就是从这个工厂中获取到的对象
Spring 三级缓存放入二级缓存做了什么事情?
ObjectFactory.getObject() 触发 getEarlyBeanReference()方法之后才放入二级缓存;
getEarlyBeanReference():实际上就是调用了后置处理器的getEarlyBeanReference
为什么要使用三级缓存呢?二级缓存能解决循环依赖吗?
如果要使用二级缓存解决循环依赖,意味着所有Bean在实例化后就要完成AOP代理,这样违背了Spring设计的原则,Spring在设计之初就是通过AnnotationAwareAspectJAutoProxyCreator这个后置处理器来在Bean生命周期的最后一步来完成AOP代理,而不是在实例化后就立马进行AOP代理。