首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.
下面我们就进入正题,看看spring的循环依赖源码.
一、getBean整体流程
目标很明确了,就是要看看spring如何解决循环依赖的.
代码入口是refresh()#finishbeanfactoryInitialization(beanfactory);
二、拆解研究流程中的每一步
调用方法beanfactory.preInstantiateSingletons();实例化剩余的单例bean. 为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类,postProcessor等.
2.1 入口
1 @Override 2 public void preInstantiateSingletons() throws BeansException { 3 if (logger.isTraceEnabled()) { 4 logger.trace("Pre-instantiating singletons in " + this); 5 } 6 7 8 // 获取容器中所有bean定义的名字 9 List<String> beanNames = new ArrayList<>(.beanDefinitionNames); 10 11 Trigger initialization of all non-lazy singleton beans... 12 /** 13 * 第一步: 循环bean定义的name 14 */ 15 for (String beanName : beanNames) { 16 获取bean定义 17 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 18 生产bean定义的条件: 不是抽象的,是单例的,不是懒加载的. 符合这个标准的,最后才会调用getBean()生产bean 19 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 20 这里判断是不是工厂bean,这里和beanfactory不是一个意思,判断当前这个bean是否实现了beanfactory的接口 21 (isfactorybean(beanName)) { 22 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 23 (bean instanceof factorybean) { 24 final factorybean<?> factory = (factorybean<?>) bean; 25 boolean isEagerInit; 26 if (System.getSecurityManager() != null && factory instanceof Smartfactorybean) { 27 isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) 28 ((Smartfactorybean<?>) factory)::isEagerInit,29 getAccessControlContext()); 30 } 31 else { 32 isEagerInit = (factory instanceof Smartfactorybean && 33 ((Smartfactorybean<?>) factory).isEagerInit()); 3435 (isEagerInit) { 36 获取bean 37 getBean(beanName); 3839 } 40 } 41 { // 第二步: 调用bean定义 42 getBean(beanName); 4344 } 45 } 46 47 Trigger post-initialization callback for all applicable beans... 48 51 52 从缓存中得到实例instance 53 Object singletonInstance = getSingleton(beanName); 54 (singletonInstance instanceof SmartInitializingSingleton) { 55 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 56 null) { 57 AccessController.doPrivileged((PrivilegedAction<Object>) () ->58 smartSingleton.afterSingletonsInstantiated(); 59 return ; 60 },getAccessControlContext()); 6162 63 smartSingleton.afterSingletonsInstantiated(); 64656667 }
首先,循环bean定义,这和我们模拟spring循环的第一步是一样的.
第二步: 判断从BeanDefinitionMap中取出来的这个bean是否满足生产bean的条件
我们注意代码注释中, 生产bean定义的条件: 不是抽象的,最后才会调用getBean()生产bean
然后:调用getBean()
到目前为止,我们完成了上图源码图的第一部分:
2.2 创建bean前的准备工作
接下来看看getBean().doGetBean()方法
1 protected <T> T doGetBean(final String name,@Nullable final Class<T> requiredType,1)">2 @Nullable final Object[] args,boolean typeCheckOnly) throws BeansException { 3 4 // 第一步: 转换bean name. 在这里传入进来的name可能是别名,也有可能是工厂bean的name,所以在这里进行一个转换 5 final String beanName = transformedBeanName(name); 6 Object bean; 7 Eagerly check singleton cache for manually registered singletons. 9 // 第二步: 尝试去缓存中获取对象,如果没有获取到就创建bean 10 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == ) { 12 13 判断当前类是否是正在创建中 14 (isSingletonCurrentlyInCreation(beanName)) { 15 logger.trace(Returning eagerly cached instance of singleton bean '" + beanName + 16 ' that is not fully initialized yet - a consequence of a circular reference"17 } 18 { 19 logger.trace(Returning cached instance of singleton bean '" + beanName + '2021 } 22 bean = getObjectForBeanInstance(sharedInstance,name,beanName,2324 25 26 Fail if we're already creating this bean instance: 27 We're assumably within a circular reference. 28 * 29 * 判断当前的bean是不是多例,如果是这抛出异常 30 * 31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean 32 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入 33 * 34 * 如果是多例的bean,当前正在创建bean,也会抛出异常---这也是循环依赖的问题 35 */ 36 (isPrototypeCurrentlyInCreation(beanName)) { 37 throw new BeanCurrentlyInCreationException(beanName); 39 40 * 41 * 下面这段代码是关于子父容器的,只有spring mvc继承自spring,才会有子父容器的问题. 42 43 Check if bean definition exists in this factory. 44 beanfactory parentbeanfactory = getParentbeanfactory(); 45 if (parentbeanfactory != null && !containsBeanDefinition(beanName)) { 46 Not found -> check parent. 47 String nameToLookup = originalBeanName(name); 48 (parentbeanfactory instanceof Abstractbeanfactory) { 49 return ((Abstractbeanfactory) parentbeanfactory).doGetBean( 50 nameToLookup,requiredType,args,typeCheckOnly); 5152 else if (args != 53 Delegation to parent with explicit args. 54 (T) parentbeanfactory.getBean(nameToLookup,args); 55if (requiredType != 57 No args -> delegate to standard getBean method. 58 parentbeanfactory.getBean(nameToLookup,requiredType); 5960 61 (T) parentbeanfactory.getBean(nameToLookup); 6264 65 * 66 * 方法参数typeCheckOnly是用来判断#getBean()方法时,表示是否为仅仅进行类型检查,67 * 如果不仅仅做类型检查,而是创建bean对象,则需要调用#markBeanAsCreated(String name) 68 * 69 70 if (!typeCheckOnly) { 71 markBeanAsCreated(beanName); 7273 74 try75 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); 76 checkMergedBeanDefinition(mbd,1)">77 78 Guarantee initialization of beans that the current bean depends on. 79 * 80 * 现在有两个bean1,bean2,加载的时候调用的是bean1,bean2. 但如果我们想要bean2优先加载,就使用@DependOn注解 81 * 用来解析带有dependOn注解的类 82 83 String[] dependsOn = mbd.getDependsOn(); 84 if (dependsOn != 85 (String dep : dependsOn) { 86 (isDependent(beanName,dep)) { 87 BeanCreationException(mbd.getResourceDescription(),1)">88 Circular depends-on relationship between '' and '" + dep + 89 } 90 registerDependentBean(dep,beanName); 91 92 getBean(dep); 9394 catch (NoSuchBeanDefinitionException ex) { 95 96 ' depends on missing bean ',ex); 9798 } 99100 101 Create bean instance. 102 * 103 * 第三步: 创建单例bean实例 104 105 if (mbd.isSingleton()) { 处理单例bean 106 * 107 * 这里getSingleton()和上面的getSigleton不一样,上面的是从一级缓存中拿. 108 * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要,如果出现循环依赖,发现bean正在创建,就不会再创建了 109 110 sharedInstance = getSingleton(beanName,() ->111 112 createBean(beanName,mbd,args); 113114 (BeansException ex) { 115 Explicitly remove instance from singleton cache: It might have been put there 116 eagerly by the creation process,to allow for circular reference resolution. 117 Also remove any beans that received a temporary reference to the bean. 118 destroySingleton(beanName); 119 throw ex; 120121 }); 122 得到bean实例对象 123 bean = getObjectForBeanInstance(sharedInstance,mbd); 124125 126 if (mbd.isPrototype()) { 处理多例bean 127 It's a prototype -> create a new instance. 128 Object prototypeInstance = 129 130 当前正在创建多例bean 131 beforePrototypeCreation(beanName); 132 执行创建bean 133 prototypeInstance =134135 finally136 afterPrototypeCreation(beanName); 137138 获取bean实例对象 139 bean = getObjectForBeanInstance(prototypeInstance,1)">140141 142 else { 处理其他类型的bean 143 String scopeName = mbd.getScope(); 144 final Scope scope = this.scopes.get(scopeName); 145 if (scope == 146 new IllegalStateException(No Scope registered for scope name '" + scopeName + ); 147148 149 Object scopedInstance = scope.get(beanName,1)">150 beforePrototypeCreation(beanName); 151 152 153 } 154 155 afterPrototypeCreation(beanName); 156157 }); 158 bean = getObjectForBeanInstance(scopedInstance,1)">159160 (IllegalStateException ex) { 161 BeanCreationException(beanName,1)">162 Scope '' is not active for the current thread; consider " + 163 defining a scoped proxy for this bean if you intend to refer to it from a singleton164 ex); 165166167168 169 cleanupAfterBeanCreationFailure(beanName); 170 171172 }
在这里,首先从缓存中获取bean,看缓存中是否已经存在了
Object sharedInstance = getSingleton(beanName);
然后,如果缓存中已经存在了,那么久直接取出来. 代码如下:
if (sharedInstance != null && args == null) { (logger.isTraceEnabled()) { 判断当前bean是否是正在创建中(单例bean) (isSingletonCurrentlyInCreation(beanName)) { logger.trace(" + beanName + ); } { logger.trace(); } } bean = getObjectForBeanInstance(sharedInstance,null); }
如果是空,就说明是第一次创建,执行else的部分
首先,判断是否是正在创建的多例bean,如果是正在创建的多例bean,就抛出异常,
已经是正在创建了,说明这至少是第二次了,这里处理的是单例bean的循环依赖,不处理多例bean的循环依赖,所以抛出异常
对应的代码是这一句
*
29 * 判断当前的bean是不是多例,如果是这抛出异常
30 *
31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
32 * spring 只能解决单例对象的setter注入的循环依赖,1)">38 }
那么,接下来就是首次创建bean. 首次创建的bean有三种情况:
第一种,这个bean是单例的.
第二种,这个bean是多例的.
第三种. 其他类型
对应的代码就是这一块. 有行号,可以和上面一一对应上
if (mbd.isSingleton()) { 处理单例bean mbd.isPrototype()) { 处理多例bean else { 处理其他类型的bean 166 }
我们的重点研究对象是单例bean. 所以,重点看单例bean的实现
if (mbd.isSingleton()) { // 处理单例bean 110 sharedInstance = getSingleton(beanName,() -> { 111 try { 112 return createBean(beanName,args); 113 } 114 catch (BeansException ex) { 115 // Explicitly remove instance from singleton cache: It might have been put there 116 // eagerly by the creation process,to allow for circular reference resolution. 117 // Also remove any beans that received a temporary reference to the bean. 118 destroySingleton(beanName); 119 throw ex; 120 } }); 123 bean =124 }
这里的重点是调用了getSingleton(beanName,FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject().
这个接口在这里这是进行了定义,并不会执行. 什么时候执行呢? 后面调用的时候执行.
下面来看看getSingleton()方法,钩子方法也是在这里被调用的.
public Object getSingleton(String beanName,ObjectFactory<?> singletonFactory) { 2 Assert.notNull(beanName,Bean name must not be null3 synchronized (.singletonObjects) { 4 // 第一步: 从一级缓存中获取单例对象 5 Object singletonObject = this.singletonObjects.(beanName); 6 if (singletonObject == 7 .singletonsCurrentlyInDestruction) { 8 BeanCreationNotAllowedException(beanName,1)">9 Singleton bean creation not allowed while singletons of this factory are in destruction 10 (Do not request a bean from a beanfactory in a destroy method implementation!)1112 (logger.isDebugEnabled()) { 13 logger.debug(Creating shared instance of singleton bean '1415 // 第二步: 将bean添加到singletonsCurrentlyInCreation中,表示bean正在创建 16 beforeSingletonCreation(beanName); 17 boolean newSingleton = false18 boolean recordSuppressedExceptions = (this.suppressedExceptions == 19 (recordSuppressedExceptions) { 20 this.suppressedExceptions = new LinkedHashSet<>(); 22 23 // 第三步: 这里调用getObject()钩子方法,就会回调匿名函数,调用singletonFactory的createBean() 24 singletonObject = singletonFactory.getObject(); 25 newSingleton = true2627 28 Has the singleton object implicitly appeared in the meantime -> 29 if yes,proceed with it since the exception indicates that state. 30 singletonObject = (beanName); 31 32 3335 (BeanCreationException ex) { 36 37 for (Exception suppressedException : .suppressedExceptions) { ex.addRelatedCause(suppressedException); 41 43 44 45 4647 afterSingletonCreation(beanName); 4849 (newSingleton) { addSingleton(beanName,singletonObject); 5253 singletonObject; 5455 }
这里是调用getBean().
第一步: 去一级缓存中取成熟的单例bean. 如果拿到了,就直接返回. 如果没拿到. 那么执行创建.
第二步: 在创建之前,先把这个bean放入到正在创建的单例bean集合中. 标记这个bean正在创建中
第三步: 就是调用钩子方法getObject()了. 这个方法的方法体是在上面定义的. 其内容是去创建实例
sharedInstance = getSingleton(beanName,1)"> { { // 这里定义了一个钩子函数. 此时只是定义,并不执行. 在真正需要创建bean的地方才会执行 return createBean(beanName,args); } (BeansException ex) { Explicitly remove instance from singleton cache: It might have been put there Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); ex; } });
这里的代码逻辑是完成了创建之前的逻辑
2.3 创建bean
下面看看创建bean的过程
1 protected Object doCreateBean(final String beanName,final RootBeanDefinition mbd,final @Nullable Object[] args) 2 throws BeanCreationException { 3 4 Instantiate the bean. 5 BeanWrapper instanceWrapper = ; 6 (mbd.isSingleton()) { 7 instanceWrapper = .factorybeanInstanceCache.remove(beanName); 8 } 9 if (instanceWrapper == ) { 10 * 11 * 第一步: 实例化 12 * 这里面的调用链非常深,后面再看 13 * bean实例化有两种方式 14 * 1. 使用反射: 使用反射也有两种方式, 15 * a. 通过无参构造函数 (默认的方式) 16 * 从beanDefinition中可以得到beanClass,1)"> 17 * ClassName = BeanDefinition.beanClass 18 * Class clazz = Class.forName(ClassName); 19 * clazz.newInstance(); 20 * 这样就可以实例化bean了 21 * 22 * b. 通过有参函数. 23 * ClassName = BeanDefinition.beanClass 24 25 * Constractor con = class.getConstractor(args....) 26 * con.newInstance(); 27 28 * 2. 使用工厂 29 * 我们使用@Bean的方式,就是使用的工厂模式,自己控制实例化过程 30 31 */ 32 instanceWrapper = createBeanInstance(beanName,args); 33 34 这里使用了装饰器的设计模式 35 final Object bean = instanceWrapper.getWrappedInstance(); 36 Class<?> beanType = instanceWrapper.getWrappedClass(); 37 if (beanType != NullBean.class 38 mbd.resolvedTargetType = beanType; 39 40 41 Allow post-processors to modify the merged bean definition. 42 允许后置处理器修改已经合并的beanDefinition 43 synchronized (mbd.postProcessingLock) { 44 mbd.postProcessed) { 45 { 46 applyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName); 47 } 48 (Throwable ex) { 49 50 Post-processing of merged bean definition Failed 51 52 mbd.postProcessed = 53 } 54 55 56 57 * 缓存单例bean到三级缓存中,以防止循环依赖 58 * 判断是否是早期引用的bean,如果是,则允许提前暴露引用 59 * 60 * 判断是否能够早起暴露的条件 61 * 1. 是单例 62 * 2. 允许循环依赖 63 * 3. 正在创建的bean 64 65 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && 66 isSingletonCurrentlyInCreation(beanName)); 67 (earlySingletonExposure) { 68 (logger.isTraceEnabled()) { 69 logger.trace(Eagerly caching bean '" + beanName + 70 ' to allow for resolving potential circular references); 71 72 把我们的早期对象包装成一个singletonFactory对象,该对象提供了getObject()方法,把静态的bean放到三级缓存中去了. 73 addSingletonFactory(beanName,1)"> getEarlyBeanReference(beanName,bean)); 74 75 76 Initialize the bean instance. 77 Object exposedObject = bean; 78 79 第二步:填充属性,给属性赋值(调用set方法) 这里也是调用的后置处理器 80 populateBean(beanName,instanceWrapper); 81 // 第三步: 初始化. 82 exposedObject = initializeBean(beanName,exposedObject,mbd); 83 84 85 if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { 86 (BeanCreationException) ex; 87 88 89 BeanCreationException( 90 mbd.getResourceDescription(),1)">Initialization of bean Failed 91 92 93 94 95 * 初始化完成以后,判断是否是早期的对象 96 * 是循环依赖. 才会走进这里来 97 98 99 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false,要求只能在一级二级缓存中取 100 正常的普通的bean(不存在循环依赖的bean) 创建的过程中,不会把三级缓存提升到二级缓存中. 101 Object earlySingletonReference = getSingleton(beanName,1)">102 if (earlySingletonReference != 103 if (exposedObject == bean) { 104 exposedObject = earlySingletonReference; 105 106 this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { 107 String[] dependentBeans = getDependentBeans(beanName); 108 Set<String> actualDependentBeans = (dependentBeans.length); 109 (String dependentBean : dependentBeans) { 110 removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { 111 actualDependentBeans.add(dependentBean); 112 } 113 } 114 actualDependentBeans.isEmpty()) { 115 BeanCurrentlyInCreationException(beanName,1)">116 Bean with name '' has been injected into other beans [" + 117 StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + 118 ] in its raw version as part of a circular reference,but has eventually been 119 wrapped. This means that said other beans do not use the final version of the 120 bean. This is often the result of over-eager type matching - consider using 121 'getBeanNamesForType' with the 'allowEagerInit' flag turned off,for example.122 123 124 125 126 127 Register bean as disposable. 128 129 registerDisposableBeanIfNecessary(beanName,bean,1)">130 131 (BeanDefinitionValidationException ex) { 132 133 mbd.getResourceDescription(),1)">Invalid destruction signature134 135 136 exposedObject; 137 }
首先,实例化bean,实例化的方式有两种. 一种是通过反射,另一种是通过动态
1 2 3 4 5 * 1. 使用反射: 使用反射也有两种方式,1)"> 6 7 8 9 10 11 12 13 14 15 16 17 18 19 * 2. 使用工厂 20 21 22 23 instanceWrapper = createBeanInstance(beanName,args);
判断是否是早期暴露的bean. 满足早期暴露的bean的三个条件是
1. 是单例的
2. 允许循环依赖
3. bean已经是处在正在创建中的行列了.
判断是否能够早起暴露的条件 * 1. 是单例 * 2. 允许循环依赖 * 3. 正在创建的bean */ boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
创建bean的第二步: 属性赋值
在这里会判断,是否带有@Autowired的属性. 分为两种一种是Name,一种是Type
@SuppressWarnings(deprecation") for postProcessPropertyValues protected populateBean(String beanName,RootBeanDefinition mbd,@Nullable BeanWrapper bw) { if (bw == ) { (mbd.hasPropertyValues()) { BeanCreationException( mbd.getResourceDescription(),1)">Cannot apply property values to null instance); } { Skip property population phase for null instance. ; } } Give any InstantiationAwareBeanPostProcessors the opportunity to modify the state of the bean before properties are set. This can be used,for example,1)"> to support styles of field injection. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { (BeanPostProcessor bp : getBeanPostProcessors()) { (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; ibp.postProcessAfterInstantiation(bw.getWrappedInstance(),beanName)) { ; } } } } PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : ); 判断属性是否有Autowired注解 int resolvedAutowireMode = mbd.getResolvedAutowireMode(); Autowired是根据名字或者根据类型 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName,bw,newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName,newPvs); } pvs = newPvs; } ...... }
如果按照名字注入
1 autowireByName( String beanName,AbstractBeanDefinition mbd,BeanWrapper bw,MutablePropertyValues pvs) { 3 4 String[] propertyNames = unsatisfiedNonSimpleProperties(mbd,bw); 5 (String propertyName : propertyNames) { 6 (containsBean(propertyName)) { 7 // 调用getBean 8 Object bean = getBean(propertyName); pvs.add(propertyName,bean); registerDependentBean(propertyName,1)">11 12 logger.trace(Added autowiring by name from bean name '13 ' via property '" + propertyName + ' to bean named '17 18 logger.trace(Not autowiring property '' of bean '19 ' by name: no matching bean found22 23 }
会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了.
按类型注入也是一样的.
只是解析bean的方式不同.
创建bean的第三步: 初始化
// 第三步: 初始化. exposedObject = initializeBean(beanName,mbd);
在初始化bean的时候,会调用很多的aware. 还会调用init-method方法. 以及bean的后置处理器.
第四步:删除实例化和静态方法在缓存中的数据
* * 初始化完成以后,判断是否是早期的对象 * 是循环依赖. 才会走进这里来 */ (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName,1)">); ) { bean) { exposedObject = earlySingletonReference; } hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = (dependentBeans.length); (String dependentBean : dependentBeans) { removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } actualDependentBeans.isEmpty()) { " + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + " + ); } } } }
removeSingletonIfCreatedForTypeCheckOnly调用方法,删除缓存.
这既是getBean()整个的过程. 中间还有很多细节,没有往里面深入的看,因为spring代码非常的深,看的太深就忘了我们的目标了. 结合之前手写的spring循环依赖的思想看,还是可以看得懂的.
三. 接下来有几个问题
问题1: 为什么需要二级缓存和三级缓存?
一级缓存: 用来存储完整的bean
二级缓存: 用来存储早期的,纯净的bean,也就是没有注入属性的bean
三级缓存: 存的是函数的接口,主要目的是为了解耦
二级缓存 和三级缓存 结合起来,解决了循环依赖下的AOP动态代理的问题
问题2:有没有解决构造函数的循环依赖
答案是没有. 因为构造函数是在实例化的时候构建的. 这个时候bean都还没有创建,所以没有办法处理循环依赖.如果出现构造函数的循环依赖,是会直接报错的..
问题3:有没有解决多例下的循环依赖
也是没有的,因为我们会判断,如果是多例,那么会抛出异常
1 /** 2 * 第二步: 判断当前bean是否是正在创建中的多例bean,如果是就抛出异常 3 * 4 * 2. 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean 5 * spring 只能解决单例对象的setter注入的循环依赖,不能解决构造器注入 6 * 7 * 如果是多例的bean,也会抛出异常---这也是循环依赖的问题 8 */ 9 (isPrototypeCurrentlyInCreation(beanName)) { 10 BeanCurrentlyInCreationException(beanName); 11 }