Spring加载流程&Bean的生命周期
推荐篇博文 Spring中bean的生命周期(最详细)
循环依赖
解决循环依赖的关键是将【实例化】与【初始化】两个过程分开。
二级缓存
假设只使用二级缓存,能否解决循环依赖问题?答案是可以。 但是这仅限于在未使用AOP生成代理对象的情况下。
代理对象实例化的时候,实例化对象是原始对象 若没有三级缓存,此时若根据类名直接获取对象的话,获取的是原始对象 而我们想要的肯定是通过类名直接获取代理对象 所以Spring在类加载过程中,直接将实例化的对象放入三级缓存中 从三级缓存中获取类对象的时候,判断类是否被代理,若被代理则返回代理对象
三级缓存
Spring在启动过程中,使用到了三个map,称为三级缓存。
/** * Cache of singleton objects: bean name to bean instance. * 【一级缓存】用于存放完全初始化好的 bean,从该缓存中取出的 bean 可以直接使用。 */private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** * Cache of singleton factories: bean name to ObjectFactory. * 【三级缓存】用于存放 bean 工厂对象ObjectFactory(三级缓存中Bean的代理对象) * ObjectFactory.getObject()方法描述了如何获取这个三级缓存的对象。 */private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** * Cache of early singleton objects: bean name to bean instance. * 【二级缓存】用于存放提前暴露的单例对象的cache,原始的 bean 对象(尚未填充属性,半成品bean)。 */private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
/** * Names of beans that are currently in creation. * 正在创建中的beanName */private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
//缓存查找bean,双重检查提高并发效率@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) { //从一级缓存获取bean Object singletonObject = this.singletonObjects.get(beanName); //一级缓存中不存在,而且是在创建中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { //从二级缓存中获取bean singletonObject = this.earlySingletonObjects.get(beanName); //二级缓存中不存在,而且允许循环依赖 if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) { //从一级缓存获取bean singletonObject = this.singletonObjects.get(beanName); //一级缓存中不存在 if (singletonObject == null) { //从二级缓存中获取bean singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { //从三级缓存中获取返回扩展对象的工厂方法 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //获取扩展对象 singletonObject = singletonFactory.getObject(); //放入二级缓存 this.earlySingletonObjects.put(beanName, singletonObject); //从三级缓存中移除 this.singletonFactories.remove(beanName); } } } }
} } return singletonObject;}
评论