掃描完Bean的需要自動注入的屬性信息之后,接著回來doCreateBean,代碼走到getEarlyBeanReference
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
// ...
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
// 官方注釋說明這里采取緩存的方式來處理Bean的循環(huán)引用
boolean earlySingletonExposure
= (mbd.isSingleton() && this.allowCircularReferences
&& isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// ...
}
/**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* 將一個ObjectFactory緩存到三級緩存singletonFactories
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* 嘗試從Bean緩存中獲取提前暴露出來的其他Bean,避免循環(huán)依賴的情況
* @param beanName the name of the bean (for error handling purposes)
* @param mbd the merged bean definition for the bean
* @param bean the raw bean instance
* @return the object to expose as bean reference
*/
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp
= (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
這個方法主要還是配合Spring處理兩個Bean之間的循環(huán)引用使用的,Spring將正在創(chuàng)建的Bean經(jīng)過這個方法的處理之后,緩存到第三級緩存singletonFactories
擴展:以AspectJAwareAdvisorAutoProxyCreator為例,簡述SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference的應用
前文Bean實例化1中,介紹了AspectJAwareAdvisorAutoProxyCreator通過繼承AbstractAutoProxyCreator實現(xiàn)了SmartInstantiationAwareBeanPostProcessor接口,在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法中緩存了不需要創(chuàng)建代理的對象,當執(zhí)行SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference方法的時候,會根據(jù)之前緩存的信息,決定是否需要返回當前Bean的代理對象
public abstract class AbstractAutoProxyCreator
extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
@Override
public Object getEarlyBeanReference(Object bean, String beanName)
throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
this.earlyProxyReferences.add(cacheKey);
}
return wrapIfNecessary(bean, beanName, cacheKey);
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 校驗當前Bean是否需要生成代理對象
if (StringUtils.hasLength(beanName)
&& this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass())
|| shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
// 創(chuàng)建代理對象
Object[] specificInterceptors
= getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName,
specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
}
因此SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference主要還是為了解決創(chuàng)建Bean的過程中,避免產(chǎn)生循環(huán)依賴的問題,緩存當前的Bean(可以是Bean,也可以是Bean的代理對象)到三級緩存中,假設產(chǎn)生了循環(huán)依賴,相互依賴的Bean可以從三級緩存中獲取到當前創(chuàng)建到一半的Bean進行屬性裝配