这个类中的成员变量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();
}
}