提交 8d8e218b 编写于 作者: J Juergen Hoeller

Consistent FactoryBean cache visibility in concurrent creation scenarios

Issue: SPR-16625
Issue: SPR-16627
上级 937cd48f
......@@ -927,12 +927,16 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
if (bw != null) {
return (FactoryBean<?>) bw.getWrappedInstance();
}
Object beanInstance = getSingleton(beanName, false);
if (beanInstance instanceof FactoryBean) {
return (FactoryBean<?>) beanInstance;
}
if (isSingletonCurrentlyInCreation(beanName) ||
(mbd.getFactoryBeanName() != null && isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
return null;
}
Object instance = null;
Object instance;
try {
// Mark this bean as currently in creation, even if just partially.
beforeSingletonCreation(beanName);
......@@ -1845,8 +1849,21 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
*/
@Override
protected void removeSingleton(String beanName) {
super.removeSingleton(beanName);
this.factoryBeanInstanceCache.remove(beanName);
synchronized (getSingletonMutex()) {
super.removeSingleton(beanName);
this.factoryBeanInstanceCache.remove(beanName);
}
}
/**
* Overridden to clear FactoryBean instance cache as well.
*/
@Override
protected void clearSingletonCache() {
synchronized (getSingletonMutex()) {
super.clearSingletonCache();
this.factoryBeanInstanceCache.clear();
}
}
......
......@@ -392,11 +392,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
// No entry yet -> fully synchronized manipulation of the containedBeans Set
synchronized (this.containedBeanMap) {
containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans == null) {
containedBeans = new LinkedHashSet<>(8);
this.containedBeanMap.put(containingBeanName, containedBeans);
}
containedBeans = this.containedBeanMap.computeIfAbsent(containingBeanName, k -> new LinkedHashSet<>(8));
containedBeans.add(containedBeanName);
}
registerDependentBean(containedBeanName, containingBeanName);
......@@ -418,19 +414,12 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
// No entry yet -> fully synchronized manipulation of the dependentBeans Set
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans = this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
......@@ -525,6 +514,14 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();
}
/**
* Clear all cached singleton instances in this registry.
* @since 4.3.15
*/
protected void clearSingletonCache() {
synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
......
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -214,17 +214,21 @@ public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanReg
*/
@Override
protected void removeSingleton(String beanName) {
super.removeSingleton(beanName);
this.factoryBeanObjectCache.remove(beanName);
synchronized (getSingletonMutex()) {
super.removeSingleton(beanName);
this.factoryBeanObjectCache.remove(beanName);
}
}
/**
* Overridden to clear the FactoryBean object cache as well.
*/
@Override
public void destroySingletons() {
super.destroySingletons();
this.factoryBeanObjectCache.clear();
protected void clearSingletonCache() {
synchronized (getSingletonMutex()) {
super.clearSingletonCache();
this.factoryBeanObjectCache.clear();
}
}
/**
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册