Revised RootBeanDefinition's externallyManaged* Sets to rely on postProcessingLock
This allows us to avoid early initialization of footprint-heavy ConcurrentHashMaps, and reuses the existing postProcessingLock which will typically be active already when registerExternallyManaged* calls come in from the bean factory's post-processing phase.
Issue: SPR-11343
(cherry picked from commit a599b57
)
This commit is contained in:
parent
aa1babdfde
commit
d9ab6aaf6c
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.beans.factory.support;
|
package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ public class ChildBeanDefinition extends AbstractBeanDefinition {
|
||||||
* @param original the original bean definition to copy from
|
* @param original the original bean definition to copy from
|
||||||
*/
|
*/
|
||||||
public ChildBeanDefinition(ChildBeanDefinition original) {
|
public ChildBeanDefinition(ChildBeanDefinition original) {
|
||||||
super(original);
|
super((BeanDefinition) original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,8 @@ package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Map;
|
import java.util.HashSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
@ -48,19 +48,10 @@ import org.springframework.util.Assert;
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public class RootBeanDefinition extends AbstractBeanDefinition {
|
public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
|
|
||||||
// using a ConcurrentHashMap as a Set
|
boolean allowCaching = true;
|
||||||
private final Map<Member, Boolean> externallyManagedConfigMembers = new ConcurrentHashMap<Member, Boolean>(0);
|
|
||||||
|
|
||||||
// using a ConcurrentHashMap as a Set
|
|
||||||
private final Map<String, Boolean> externallyManagedInitMethods = new ConcurrentHashMap<String, Boolean>(0);
|
|
||||||
|
|
||||||
// using a ConcurrentHashMap as a Set
|
|
||||||
private final Map<String, Boolean> externallyManagedDestroyMethods = new ConcurrentHashMap<String, Boolean>(0);
|
|
||||||
|
|
||||||
private BeanDefinitionHolder decoratedDefinition;
|
private BeanDefinitionHolder decoratedDefinition;
|
||||||
|
|
||||||
boolean allowCaching = true;
|
|
||||||
|
|
||||||
private volatile Class<?> targetType;
|
private volatile Class<?> targetType;
|
||||||
|
|
||||||
boolean isFactoryMethodUnique = false;
|
boolean isFactoryMethodUnique = false;
|
||||||
|
@ -87,6 +78,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
|
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
|
||||||
volatile Boolean beforeInstantiationResolved;
|
volatile Boolean beforeInstantiationResolved;
|
||||||
|
|
||||||
|
private Set<Member> externallyManagedConfigMembers;
|
||||||
|
|
||||||
|
private Set<String> externallyManagedInitMethods;
|
||||||
|
|
||||||
|
private Set<String> externallyManagedDestroyMethods;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new RootBeanDefinition, to be configured through its bean
|
* Create a new RootBeanDefinition, to be configured through its bean
|
||||||
|
@ -225,9 +222,9 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
* @param original the original bean definition to copy from
|
* @param original the original bean definition to copy from
|
||||||
*/
|
*/
|
||||||
public RootBeanDefinition(RootBeanDefinition original) {
|
public RootBeanDefinition(RootBeanDefinition original) {
|
||||||
super(original);
|
super((BeanDefinition) original);
|
||||||
this.decoratedDefinition = original.decoratedDefinition;
|
|
||||||
this.allowCaching = original.allowCaching;
|
this.allowCaching = original.allowCaching;
|
||||||
|
this.decoratedDefinition = original.decoratedDefinition;
|
||||||
this.targetType = original.targetType;
|
this.targetType = original.targetType;
|
||||||
this.isFactoryMethodUnique = original.isFactoryMethodUnique;
|
this.isFactoryMethodUnique = original.isFactoryMethodUnique;
|
||||||
}
|
}
|
||||||
|
@ -252,6 +249,20 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a target definition that is being decorated by this bean definition.
|
||||||
|
*/
|
||||||
|
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
|
||||||
|
this.decoratedDefinition = decoratedDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the target definition that is being decorated by this bean definition, if any.
|
||||||
|
*/
|
||||||
|
public BeanDefinitionHolder getDecoratedDefinition() {
|
||||||
|
return this.decoratedDefinition;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the target type of this bean definition, if known in advance.
|
* Specify the target type of this bean definition, if known in advance.
|
||||||
*/
|
*/
|
||||||
|
@ -294,37 +305,52 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||||
this.externallyManagedConfigMembers.put(configMember, Boolean.TRUE);
|
synchronized (this.postProcessingLock) {
|
||||||
|
if (this.externallyManagedConfigMembers == null) {
|
||||||
|
this.externallyManagedConfigMembers = new HashSet<Member>(1);
|
||||||
|
}
|
||||||
|
this.externallyManagedConfigMembers.add(configMember);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||||
return this.externallyManagedConfigMembers.containsKey(configMember);
|
synchronized (this.postProcessingLock) {
|
||||||
|
return (this.externallyManagedConfigMembers != null &&
|
||||||
|
this.externallyManagedConfigMembers.contains(configMember));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||||
this.externallyManagedInitMethods.put(initMethod, Boolean.TRUE);
|
synchronized (this.postProcessingLock) {
|
||||||
|
if (this.externallyManagedInitMethods == null) {
|
||||||
|
this.externallyManagedInitMethods = new HashSet<String>(1);
|
||||||
|
}
|
||||||
|
this.externallyManagedInitMethods.add(initMethod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||||
return this.externallyManagedInitMethods.containsKey(initMethod);
|
synchronized (this.postProcessingLock) {
|
||||||
|
return (this.externallyManagedInitMethods != null &&
|
||||||
|
this.externallyManagedInitMethods.contains(initMethod));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||||
this.externallyManagedDestroyMethods.put(destroyMethod, Boolean.TRUE);
|
synchronized (this.postProcessingLock) {
|
||||||
|
if (this.externallyManagedDestroyMethods == null) {
|
||||||
|
this.externallyManagedDestroyMethods = new HashSet<String>(1);
|
||||||
|
}
|
||||||
|
this.externallyManagedDestroyMethods.add(destroyMethod);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||||
return this.externallyManagedDestroyMethods.containsKey(destroyMethod);
|
synchronized (this.postProcessingLock) {
|
||||||
}
|
return (this.externallyManagedDestroyMethods != null &&
|
||||||
|
this.externallyManagedDestroyMethods.contains(destroyMethod));
|
||||||
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
|
}
|
||||||
this.decoratedDefinition = decoratedDefinition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BeanDefinitionHolder getDecoratedDefinition() {
|
|
||||||
return this.decoratedDefinition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue