這個類中的成員變量private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);主要是緩存通過FactoryBean的getObject()方法構造出來的單例Bean。這裏發現緩存通過FactoryBean的getObject()方法構造出來的單例Bean的Map和正常的單例Bean實例存放的map不是同一個。DefaultSingletonBeanRegistry的singletonObjects中存放FactoryBean的單例實例,而factoryBeanObjectCache中存放的是由FactoryBean的getObject()方法所產生的實例,所以並不衝突
源碼註釋的大概翻譯
/**
* 支持需要處理
* {@link org.springframework.beans.factory.FactoryBean}實例的單例註冊表的基類,並與
* {@link DefaultSingletonBeanRegistry}的單例管理集成在一起。
*
* 用作{@link AbstractBeanFactory}的基類。
* @author Juergen Hoeller
* @since 2.5.1
*/
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
/** 由FactoryBeans創建的單例對象的緩存:對象的FactoryBean名稱。 */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
/**
* 確定給定FactoryBean的類型。
* @param factoryBean 要檢查的FactoryBean實例
* @return 返回FactoryBean的對象類型,或者如果尚未確定類型,則返回{@code null}
* or {@code null} if the type cannot be determined yet
*/
@Nullable
protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Class<?>>)
factoryBean::getObjectType, getAccessControlContext());
}
else {
return factoryBean.getObjectType();
}
}
catch (Throwable ex) {
// Thrown from the FactoryBean's getObjectType implementation.
logger.info("FactoryBean threw exception from getObjectType, despite the contract saying " +
"that it should return null if the type of its object cannot be determined yet", ex);
return null;
}
}
/**
* 以緩存形式從給定的FactoryBean獲取要公開的對象
* 快速檢查最小同步。
* @param beanName bean的名稱
* @return 返回從FactoryBean獲得的對象,如果不可用返回 {@code null}
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
/**
* 獲取要從給定FactoryBean中公開的對象
* @param factory factoryFactory實例的工廠
* @param beanName Bean的名稱
* @param shouldPostProcess Bean是否要進行後處理
* @return 返回從FactoryBean獲得的對象
* @throws BeanCreationException 如果FactoryBean對象創建失敗
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
/**
* 獲取要從給定FactoryBean中公開的對象。
* @param factory FactoryBean實例
* @param beanName Bean的名稱
* @return 返回從FactoryBean獲得的對象
* @throws BeanCreationException 如果FactoryBean對象創建失敗
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
/**
* 對從FactoryBean獲得的給定對象進行後置處理。
* 結果對象將暴露給bean引用。
* 默認實現只是按原樣返回給定的對象。
* 子類可以覆蓋它,例如,以應用後處理器。
* @param object 從FactoryBean獲得的對象。
* @param beanName bean的名稱
* @return 返回對象以公開
* @throws org.springframework.beans.BeansException 後置處理過程失敗
*/
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
return object;
}
/**
* 如果可能,獲取給定bean的FactoryBean。
* @param beanName Bean的名稱
* @param beanInstance 相應的bean實例
* @return 將bean實例作爲FactoryBean返回
* @throws BeansException 如果給定的bean無法公開爲FactoryBean
*/
protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanCreationException(beanName,
"Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
}
return (FactoryBean<?>) beanInstance;
}
/**
* 重寫以清除FactoryBean對象緩存。
*/
@Override
protected void removeSingleton(String beanName) {
synchronized (getSingletonMutex()) {
super.removeSingleton(beanName);
this.factoryBeanObjectCache.remove(beanName);
}
}
/**
* 重寫以清除FactoryBean對象緩存。
*/
@Override
protected void clearSingletonCache() {
synchronized (getSingletonMutex()) {
super.clearSingletonCache();
this.factoryBeanObjectCache.clear();
}
}
/**
* 返回此bean工廠的安全上下文。如果設置了安全管理器
* 則將使用此方法返回的安全上下文的特權
* 執行與用戶代碼的交互。
* @see AccessController#getContext()
*/
protected AccessControlContext getAccessControlContext() {
return AccessController.getContext();
}
}