Spring如何解决循环依赖?
- 什么是循环依赖:由于各种对象之间相互依赖,导致各对象依赖图呈现圆形(A>B,B>C,C>A), 最终导致死锁
- Spring解决循环依赖的思路是(只能解决单例,非构造方法,非原型之间的循环依赖):通过三层Map;是不等bean建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦一个bean需要依赖上个bean ,则直接使用ObjectFactory.对bean进行了提前暴露,使其他bean可以引用到bean,进而打破了对资源的请求保持,解决了循环依赖
- singletonObjects:记录了bean->beanInstance的Map集合
- earlySingletonObjects(开辟了内存空间,但是没有设置属性):记录了bean-> beanInstance的早期Map集合;当一个bean被置于earlySingletonObjects后,那么当bean还在创建时,其余的bean可以通过getBean获得bean, 用于解决单例bean的循环依赖
- singletonFactories:记录了bean->ObjectFactory之间的关系;记录了bean和创建bean的工厂之间的关系
- 为什么需要三级缓存解决循环依赖问题?
- 一级缓存可以解决循环依赖,但是instance未初始化、已经初始化放在一起,容易空指针
- 二级缓存可以解决循环依赖,但是二级缓存只能操作原始对象,而当需要AOP时,代理对象者会为容器生成与对象同名的代理对象;当容器返回时,无法确定是哪个对象
protected Object getSingleton(String beanName,boolean allowEarlyReference){ // 快速检测beanName->beanInstance(singletonObjects)的一级Map集合 Object singletonObject=this.singletonObjects.get(beanName); //如果存在,则直接返回对应的beanInstance //否则,如果一级Map集合查找不到且当前bean正在创建中,则查找(earlySingletonObjects)二级Map集合 //earlySingletonObjects也是记录了beanName->beanInstance的关系,但是earlySingletonObjects没有设置instance的属性 //只记录了最初始的instance if(singletonObject==null&&isSingletonCurrentlyInCreation(beanName)){ singletonObject=this.earlySingletonObjects.get(beanName); //如果二级Map不存在我所需要的instance且允许早期引用 if(singletonObject==null&&allowEarlyReference){ //为bean->beanInstance的一级Map集合加锁,在此创建bean的早期引用 synchronized (this.singletonObjects){ singletonObject=this.singletonObjects.get(beanName); //如果一级Map不存在bean if(singletonObject==null){ singletonObject=this.earlySingletonObjects.get(beanName); //如果二级Map不存在bean if(singletonObject==null){ ObjectFactory<?> singletonFactory=this.singletonFactories.get(beanName); //获取对应bean的ObjectFactory if(singletonFactory!=null){ //获取对应实例 singletonObject=singletonFactory.getObject(); //将当前的bean->beanInstance添加到早期二级Map集合中 this.earlySingletonObjects.put(beanName,singletonObject); //从beanObject移除对应beanName this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
getMergedLocalBeanDefinition(合并bean的定义)
- 为什么需要bean的合并?
- 为了保证bean的正确性;由于bean存在各种处理器,对bean进行处理,无法保证bean的属性在某个阶段是否存在不正确
- bean合并流程如下
- 是否能够获取bean的定义?是否允许bean定义的合并
- bean是否存在继承关系?
- bean之间的作用域是否需要修正?
protected RootBeanDefinition getMergedBeanDefinition( String beanName,BeanDefinition bd,@Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException{ synchronized (this.mergedBeanDefinitions){ RootBeanDefinition mbd=null; RootBeanDefinition previous=null; // Check with full lock now in order to enforce the same merged instance. if(containingBd==null){ //从mergedBeanDefinitions获取beanName的定义信息 mbd=this.mergedBeanDefinitions.get(beanName); } //如果不存在beanName的定义信息或者RootBeanDefinition本身允许合并 if(mbd==null||mbd.stale){ previous=mbd; //如果BeanDefinition不存在依赖关系 if(bd.getParentName()==null){ //如果BeanDefinition本身与RootBeanDefinition存在联系 if(bd instanceof RootBeanDefinition){ //则直接复制BeanDefinition并且转化为RootBeanDefinition mbd=((RootBeanDefinition)bd).cloneBeanDefinition(); } else{ //否则新建对象且转化为RootBeanDefinition mbd=new RootBeanDefinition(bd); } } //BeanDefinition之间存在依赖关系,此时进行合并 //BeanDefinition+ParentBeanDefinition=MergedBeanDefinition else{ // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try{ //对BeanDefinition的父亲进行beanName解析 String parentBeanName=transformedBeanName(bd.getParentName()); //递归合并BeanDefinition if(!beanName.equals(parentBeanName)){ pbd=getMergedBeanDefinition(parentBeanName); } else{ BeanFactory parent=getParentBeanFactory(); if(parent instanceof ConfigurableBeanFactory){ pbd=((ConfigurableBeanFactory)parent).getMergedBeanDefinition(parentBeanName); } else{ throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '"+parentBeanName+"' is equal to bean name '"+beanName+ "': cannot be resolved without a ConfigurableBeanFactory parent"); } } } catch(NoSuchBeanDefinitionException ex){ throw new BeanDefinitionStoreException(bd.getResourceDescription(),beanName, "Could not resolve parent bean definition '"+bd.getParentName()+"'",ex); } //将上一步递归产生的BeanDefinition转化为RootBeanDefinition mbd=new RootBeanDefinition(pbd); //并且从给定的bean定义(可能是子节点)覆盖此bean定义中的设置(可能是从父子继承关系复制的父节点) mbd.overrideFrom(bd); } // 如果之前没有配置scope属性,则默认设置为单例scope if(!StringUtils.hasLength(mbd.getScope())){ mbd.setScope(SCOPE_SINGLETON); } //一个非单例的bean中不能包含单例bean //在合并的过程中,可能出现父级bean为单例,而子bean不是单例. // 而这种情况是不被允许的,再次对父级bean的类型进行修正 if(containingBd!=null&&!containingBd.isSingleton()&&mbd.isSingleton()){ mbd.setScope(containingBd.getScope()); } //增加何必之后的BeanDefinition缓存 if(containingBd==null&&isCacheBeanMetadata()){ this.mergedBeanDefinitions.put(beanName,mbd); } } if(previous!=null){ copyRelevantMergedBeanDefinitionCaches(previous,mbd); } return mbd; } }
createBean
• 创建bean的一些核心操作 protected Object createBean(String beanName,RootBeanDefinition mbd,@Nullable Object[]args) throws BeanCreationException{ if(logger.isTraceEnabled()){ logger.trace("Creating instance of bean '"+beanName+"'"); } RootBeanDefinition mbdToUse=mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. Class<?> resolvedClass=resolveBeanClass(mbd,beanName); if(resolvedClass!=null&&!mbd.hasBeanClass()&&mbd.getBeanClassName()!=null){ mbdToUse=new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try{ //查找当前class及其超类的method,如果数量为0,则抛出异常; //如果数量为1,则标记此方法不需要重写 mbdToUse.prepareMethodOverrides(); } catch(BeanDefinitionValidationException ex){ throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName,"Validation of method overrides failed",ex); } try{ //当前bean是否需要代理,如果需要,则返回代理对象;bean不在按照普通bean的方式创建; //如果返回为空,则准寻普通bean的创建步骤; //这里只是bean实例化之前的处理; //给出了bean实例化之前修改BeanDefinitio的方式 //如果bean实例化前处理不为空,则启用bean实例化后置处理器 Object bean=resolveBeforeInstantiation(beanName,mbdToUse); //如果代理之前创建的bean不为空,则直接返回,bean的创建完成 if(bean!=null){ return bean; } } catch(Throwable ex){ throw new BeanCreationException(mbdToUse.getResourceDescription(),beanName, "BeanPostProcessor before instantiation of bean failed",ex); } try{ //如果代理没有执行bean的创建,则普通过程创建bean Object beanInstance=doCreateBean(beanName,mbdToUse,args); if(logger.isTraceEnabled()){ logger.trace("Finished creating instance of bean '"+beanName+"'"); } return beanInstance; } catch(BeanCreationException|ImplicitlyAppearedSingletonException ex){ // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch(Throwable ex){ throw new BeanCreationException( mbdToUse.getResourceDescription(),beanName,"Unexpected exception during bean creation",ex); } }
resolveBeforeInstantiation
• bean的代理确定,以及bean实例化之前的处理器、bean实例化之后的处理器 protected Object resolveBeforeInstantiation(String beanName,RootBeanDefinition mbd){ Object bean=null; if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)){ // Make sure bean class is actually resolved at this point. if(!mbd.isSynthetic()&&hasInstantiationAwareBeanPostProcessors()){ //确定给定BeandeDinition的目标类型 Class<?> targetType=determineTargetType(beanName,mbd); //如果目标类型不为空 if(targetType!=null){ //则进行bean创建前的处理 bean=applyBeanPostProcessorsBeforeInstantiation(targetType,beanName); //如果bean前置处理返回的bean不为空 if(bean!=null){ //则对bean进行后处理 bean=applyBeanPostProcessorsAfterInitialization(bean,beanName); } } } mbd.beforeInstantiationResolved=(bean!=null); } return bean; }
doCreateBean
• 真正创建bean protected Object doCreateBean(String beanName,RootBeanDefinition mbd,@Nullable Object[]args) throws BeanCreationException{ // Instantiate the bean. //创建一个复合bean BeanWrapper instanceWrapper=null; if(mbd.isSingleton()){ instanceWrapper=this.factoryBeanInstanceCache.remove(beanName); } if(instanceWrapper==null){ //复合bean的创建分为几种方式自动装配构造函数、默认构造函数、工厂实例化bean...... //复合bean的创建行为根据是否重写分为两种, //复合bean不存在方法重写则使用反射创建; //复合bean如果存在方法重写则通过CGLIB代理创建 instanceWrapper=createBeanInstance(beanName,mbd,args); } Object bean=instanceWrapper.getWrappedInstance(); Class<?> beanType=instanceWrapper.getWrappedClass(); if(beanType!=NullBean.class){ mbd.resolvedTargetType=beanType; } //对注解的扫描@Autowired,@PostConstruct...... synchronized (mbd.postProcessingLock){ if(!mbd.postProcessed){ try{ applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName); } catch(Throwable ex){ throw new BeanCreationException(mbd.getResourceDescription(),beanName, "Post-processing of merged bean definition failed",ex); } //标记bean合并处理完成 mbd.postProcessed=true; } } //解决循环依赖:如果bean是单例,且允许发生循环依赖,且属于正在创建中的状态 //则将bean的信息提前暴露到二级缓存中 boolean earlySingletonExposure=(mbd.isSingleton()&&this.allowCircularReferences&& isSingletonCurrentlyInCreation(beanName)); if(earlySingletonExposure){ if(logger.isTraceEnabled()){ logger.trace("Eagerly caching bean '"+beanName+ "' to allow for resolving potential circular references"); } //将bean提前暴露 addSingletonFactory(beanName,()->getEarlyBeanReference(beanName,mbd,bean)); } Object exposedObject=bean; try{ //对复合bean的填充,对各种属性的设置 populateBean(beanName,mbd,instanceWrapper); //初始化给定的复合bean实例 exposedObject=initializeBean(beanName,exposedObject,mbd); } catch(Throwable ex){ if(ex instanceof BeanCreationException&&beanName.equals(((BeanCreationException)ex).getBeanName())){ throw(BeanCreationException)ex; } else{ throw new BeanCreationException( mbd.getResourceDescription(),beanName,"Initialization of bean failed",ex); } } if(earlySingletonExposure){ Object earlySingletonReference=getSingleton(beanName,false); if(earlySingletonReference!=null){ if(exposedObject==bean){ exposedObject=earlySingletonReference; } else if(!this.allowRawInjectionDespiteWrapping&&hasDependentBean(beanName)){ String[]dependentBeans=getDependentBeans(beanName); Set<String> actualDependentBeans=new LinkedHashSet<>(dependentBeans.length); for(String dependentBean:dependentBeans){ if(!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)){ actualDependentBeans.add(dependentBean); } } if(!actualDependentBeans.isEmpty()){ throw new BeanCurrentlyInCreationException(beanName, "Bean with name '"+beanName+"' has been injected into other beans ["+ StringUtils.collectionToCommaDelimitedString(actualDependentBeans)+ "] in its raw version as part of a circular reference, but has eventually been "+ "wrapped. This means that said other beans do not use the final version of the "+ "bean. This is often the result of over-eager type matching - consider using "+ "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try{ registerDisposableBeanIfNecessary(beanName,bean,mbd); } catch(BeanDefinitionValidationException ex){ throw new BeanCreationException( mbd.getResourceDescription(),beanName,"Invalid destruction signature",ex); } return exposedObject; }