Spring如何解决循环依赖
为了解决循环依赖,Spring 使用了三级缓存。一级缓存用于存储 bean 定义。二级缓存用于存放已经创建但还没有完全初始化的前期bean实例。三级缓存用于存放完全初始化的bean实例。
当检测到循环依赖时,Spring 会创建一个部分初始化的 bean 实例并将其存储在二级缓存中。这允许 Spring 通过将部分初始化的 bean 实例注入到依赖它的另一个 bean 中来解决循环依赖。一旦解决了循环依赖,Spring 就可以完全初始化 bean 实例并将其存储在三级缓存中。
核心源码来自 Spring 框架中的 AbstractAutowireCapableBeanFactory 类。此类负责创建和初始化 bean 实例。核心部分在doCreateBean 方法种,该方法在创建新 bean 实例时调用。
以下为部分代码
/d:/study/spring-framework/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java
if (instanceWrapper == null) { // Check if instanceWrapper is null
instanceWrapper = createBeanInstance(beanName, mbd, args); // instanceWrapper if it is null
}
Object bean = instanceWrapper.getWrappedInstance(); // Get the wrapped instance from the instanceWrapper
Class<?> beanType = instanceWrapper.getWrappedClass(); // Get the wrapped class from the instanceWrapper
if (beanType != NullBean.class) { // Check if the beanType is not NullBean
mbd.resolvedTargetType = beanType; // Set the resolvedTargetType to the beanType
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) { // Synchronize on the postProcessingLock
if (!mbd.postProcessed) { // Check if the bean definition has not been post-processed
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); // Apply post-processors to the merged bean definition
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex); // Throw a BeanCreationException if post-processing fails
}
mbd.postProcessed = true; // Set the postProcessed flag to true
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName)); // Check if early singleton exposure is allowed
if (earlySingletonExposure) { // If it is allowed
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references"); // Log a message indicating that the bean is being eagerly cached
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); // Add a singleton factory for the bean
}
// Initialize the bean instance.
Object exposedObject = bean; // Set the exposedObject to the bean
try {
populateBean(beanName, mbd, instanceWrapper); // Populate the bean with property values
exposedObject = initializeBean(beanName, exposedObject, mbd); // Initialize the bean
}
catch (Throwable ex) { // Catch any exceptions that occur during initialization
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex; // If the exception is a BeanCreationException and the bean name matches, re-throw the exception
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); // Otherwise, throw a new BeanCreationException
}
}
标签:依赖,BeanCreationException,mbd,spring,beanName,instanceWrapper,bean,源码,ex
From: https://www.cnblogs.com/itqczzz/p/17312289.html