SpringIOC DI循环依赖实例详解

  

要弄清楚循环依赖

  

1,需要知道Bean初始化的两个阶段

  

①豆实例化创建实例对象(新Bean ())

  

②豆实例对象初始化(DI:注解自动注入)

  

2, DefaultSingletonBeanRegistry类中的5个容器
  

     /* *记录已将创建的单例& lt; beanName, singletonBean>*/   私人最终Map<字符串,Object>singletonObjects=new ConcurrentHashMap<祝辞(256);/* *记录singletonFactorysingeletonFactory中存放beanName和上面的①阶段的bean:豆实例化实例对象(还未初始化DI) */私人最终Map<字符串,ObjectFactory<& # 63;在祝辞singletonFactories=new HashMap<祝辞(16);/* *记录早期的singletonBean存放的也是①*/私人最终Map<字符串,Object>earlySingletonObjects=new HashMap<祝辞(16);/* *存放已经初始化后的beanName,有序*/私人最终SetregisteredSingletons=new LinkedHashSet<祝辞(256);/* *记录正在初始化的bean的beanName */私人最终SetsingletonsCurrentlyInCreation=集合。newSetFromMap(新ConcurrentHashMap<祝辞(16));      

其中跟循环依赖相关的是singletonFactories, singeletonsCurrentlyInCreation earlysingletonObjects。

  

3,循环依赖实现

  

①bean初始化前后会打标,加入到singletonsCurrentlyInCreation容器中,这个打标会在核心方法getSingleton()中起作用
  

     /* org.springframework.beans.factory.support.DefaultSingletonBeanRegistry # getSingleton (. lang。字符串,org.springframework.beans.factory.ObjectFactory<& # 63;祝辞)*/公共对象getSingleton(字符串beanName ObjectFactory<& # 63;比;singletonFactory) {   …//循环依赖相关:初始化前先singletonsCurrentlyInCreation.add (beanName)   beforeSingletonCreation (beanName);   …//λ表达式:其实是调用createBean (mbd beanName, args):豆初始化   singletonObject=singletonFactory.getObject ();   …//循环依赖相关:初始化后singletonsCurrentlyInCreation.remove (beanName)   afterSingletonCreation (beanName);   …//初始化完后//this.singletonObjects。把(beanName singletonObject);放入到单例容器中//this.singletonFactories.remove (beanName);清空循环依赖的两个打标//this.earlySingletonObjects.remove (beanName);//this.registeredSingletons.add (beanName);放入单例beanName容器中   addSingleton (beanName singletonObject);   …   }   }      

②上面singletonObject=singletonFactory.getObject()时向singletonFactories中记录了(新Bean ()), singletonFactories也会在核心方法getSingleton()中起作用
  

     /* org.springframework.beans.factory.support。AbstractAutowireCapableBeanFactory # doCreateBean */保护对象doCreateBean(最终字符串beanName,最后RootBeanDefinition mbd,最后@Nullable Object[]参数)   抛出BeanCreationException {   …//循环依赖相关逻辑://this.singletonFactories。把(beanName singletonFactory);//将实例化bean(①阶段),beanName组装成singletonFactory装入singletonFactories容器//this.earlySingletonObjects.remove (beanName);//删除earlySingletonObjects中beanName   addSingletonFactory (beanName ()→getEarlyBeanReference (beanName mbd bean));   …//实例初始化就是在这里面实现依赖注入DI的:反射实现//调用AutowiredAnnotationBeanPostProcessor.postProcessProperties   populateBean (beanName mbd instanceWrapper);   …   }      

③核心方法getSingleton

     /* org.springframework.beans.factory.support.DefaultSingletonBeanRegistry # getSingleton (. lang。字符串、布尔值)*/保护对象getSingleton(字符串beanName,布尔allowEarlyReference) {   对象singletonObject=this.singletonObjects.get (beanName);//循环依赖核心就在于这个判断,由于打标+记录了①阶段的bean//循环依赖第二次调用getBean (“a”)时,这里会直接返回第一次调用getBean (“a”)创建的①阶段的bean//而不会调用createBean (“a”)再次豆初始化(造成两个bean的循环创建)   如果(singletonObject==零,,isSingletonCurrentlyInCreation (beanName)) {   同步(this.singletonObjects) {   singletonObject=this.earlySingletonObjects.get (beanName);   如果(singletonObject==零,,allowEarlyReference) {   ObjectFactory<& # 63;比;singletonFactory=this.singletonFactories.get (beanName);   如果(singletonFactory !=null) {   singletonObject=singletonFactory.getObject ();   this.earlySingletonObjects。把(beanName singletonObject);   this.singletonFactories.remove (beanName);   }   }   }   }   返回singletonObject;   }      

④循环依赖流程
  

     

SpringIOC DI循环依赖实例详解