0
点赞
收藏
分享

微信扫一扫

对spring解决循环依赖的理解

_铁马冰河_ 2022-03-11 阅读 149

首先我感觉不能抛开问题去理解一个东西,所以这里还是再问一句:

什么是循环依赖?

循环依赖有几种,A->A ,A->B->A,A->B->C->B->A等等,由于没有更进一步研究,我说下这里可能涉及的一些更多的问题:

                                1.不同依赖形式可能导致处理方式不一样

                                2.不同的依赖注入方式可能导致spring的处理结果不一样

java bean,spring bean?

        java bean 就是java对象,spring bean由spring创建封装并管理对象,比如一个重要差别:如果ioc容器注入的bean使用了AOP去增强某个方法,那么在用注入对象调用该方法时,实际是调用了代理对象的方法。

sping中bean的生命周期?

如果先要理解spring如何解决循环依赖,先需要知道spring中bean的生命周期。

这里简单写四个相对重要的步骤(实际过程还会更复杂一些,例如bean的前后置处理器,aware获取bean在容器中的属性等等):

                 bean的创建 ...--> bean属性赋值 ...--> bean的初始化...-->(如果有AOP)等等

bean的创建:主要是生成属性未赋值对象。

bean的属性赋值:给bean的属性赋值,例如bean中依赖的bean。

bean的初始化: 执行一系列操作。

(如果使用AOP):使用动态代理去增强方法。

如何解决循环依赖?

首先要知道三级缓存

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
        //1级缓存 用于存放 已经属性赋值 初始化后的 单列BEAN
        private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
        //2级缓存 用于存在已经实例化,还未做代理属性赋值操作的 单例
        private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
        //3级缓存 存储单例BEAN的工厂
        private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
        //已经注册的单例池里的beanName
        private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
        //正在创建中的beanName
        private final Set<String> singletonsCurrentlyInCreation =
                Collections.newSetFromMap(new ConcurrentHashMap<>(16));
        //缓存查找bean  如果1级没有,从2级获取,也没有,从3级创建放入2级
        protected Object getSingleton(String beanName, boolean allowEarlyReference) {
            Object singletonObject = this.singletonObjects.get(beanName); //1级
            if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
                synchronized (this.singletonObjects) {
                    singletonObject = this.earlySingletonObjects.get(beanName); //2级
                    if (singletonObject == null && allowEarlyReference) {
                        //3级缓存  在doCreateBean中创建了bean的实例后,封装ObjectFactory放入缓存的
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            //创建未赋值的bean
                            singletonObject = singletonFactory.getObject();
                            //放入到二级缓存
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            //从三级缓存删除
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
            return singletonObject;
        }   
    }

 待续

举报

相关推荐

0 条评论