protectedvoidprepareMethodOverride(MethodOverride mo)throws BeanDefinitionValidationException { intcount= ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { thrownewBeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } elseif (count == 1) { // Mark override as not overloaded, to avoid the overhead of arg type checking. mo.setOverloaded(false); } }
// Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. // <4> 解决单例模式的循环依赖 booleanearlySingletonExposure= (mbd.isSingleton() && // 单例模式 this.allowCircularReferences && // 运行循环依赖 isSingletonCurrentlyInCreation(beanName));// 当前单例 bean 是否正在被创建 if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } // 提前将创建的 bean 实例加入到 singletonFactories 中 // 这里是为了后期避免循环依赖 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
// Initialize the bean instance. // 开始初始化 bean 实例对象 ObjectexposedObject= bean; try { // <5> 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性 // 则会递归初始依赖 bean populateBean(beanName, mbd, instanceWrapper); // <6> 调用初始化方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { thrownewBeanCreationException( mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } // <7> 循环依赖处理 if (earlySingletonExposure) { // 获取 earlySingletonReference ObjectearlySingletonReference= getSingleton(beanName, false); // 只有在存在循环依赖的情况下,earlySingletonReference 才不会为空 if (earlySingletonReference != null) { // 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强 if (exposedObject == bean) { exposedObject = earlySingletonReference; // 处理依赖 } elseif (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = newLinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { thrownewBeanCurrentlyInCreationException(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."); } } } }