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
This commit is contained in:
Juergen Hoeller 2014-01-22 14:20:33 +01:00
parent e20c927c5e
commit a599b57a74
1 changed files with 53 additions and 28 deletions

View File

@ -18,9 +18,8 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
@ -49,19 +48,10 @@ import org.springframework.util.Assert;
@SuppressWarnings("serial")
public class RootBeanDefinition extends AbstractBeanDefinition {
private final Set<Member> externallyManagedConfigMembers =
Collections.newSetFromMap(new ConcurrentHashMap<Member, Boolean>(0));
private final Set<String> externallyManagedInitMethods =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(0));
private final Set<String> externallyManagedDestroyMethods =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(0));
boolean allowCaching = true;
private BeanDefinitionHolder decoratedDefinition;
boolean allowCaching = true;
private volatile Class<?> targetType;
boolean isFactoryMethodUnique = false;
@ -91,6 +81,12 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
/** Package-visible field that indicates a before-instantiation post-processor having kicked in */
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
@ -175,8 +171,8 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
*/
public RootBeanDefinition(RootBeanDefinition original) {
super(original);
this.decoratedDefinition = original.decoratedDefinition;
this.allowCaching = original.allowCaching;
this.decoratedDefinition = original.decoratedDefinition;
this.targetType = original.targetType;
this.isFactoryMethodUnique = original.isFactoryMethodUnique;
}
@ -203,6 +199,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.
*/
@ -245,37 +255,52 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
}
}
public void registerExternallyManagedConfigMember(Member configMember) {
this.externallyManagedConfigMembers.add(configMember);
synchronized (this.postProcessingLock) {
if (this.externallyManagedConfigMembers == null) {
this.externallyManagedConfigMembers = new HashSet<Member>(1);
}
this.externallyManagedConfigMembers.add(configMember);
}
}
public boolean isExternallyManagedConfigMember(Member configMember) {
return this.externallyManagedConfigMembers.contains(configMember);
synchronized (this.postProcessingLock) {
return (this.externallyManagedConfigMembers != null &&
this.externallyManagedConfigMembers.contains(configMember));
}
}
public void registerExternallyManagedInitMethod(String initMethod) {
this.externallyManagedInitMethods.add(initMethod);
synchronized (this.postProcessingLock) {
if (this.externallyManagedInitMethods == null) {
this.externallyManagedInitMethods = new HashSet<String>(1);
}
this.externallyManagedInitMethods.add(initMethod);
}
}
public boolean isExternallyManagedInitMethod(String initMethod) {
return this.externallyManagedInitMethods.contains(initMethod);
synchronized (this.postProcessingLock) {
return (this.externallyManagedInitMethods != null &&
this.externallyManagedInitMethods.contains(initMethod));
}
}
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
this.externallyManagedDestroyMethods.add(destroyMethod);
synchronized (this.postProcessingLock) {
if (this.externallyManagedDestroyMethods == null) {
this.externallyManagedDestroyMethods = new HashSet<String>(1);
}
this.externallyManagedDestroyMethods.add(destroyMethod);
}
}
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
return this.externallyManagedDestroyMethods.contains(destroyMethod);
}
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
this.decoratedDefinition = decoratedDefinition;
}
public BeanDefinitionHolder getDecoratedDefinition() {
return this.decoratedDefinition;
synchronized (this.postProcessingLock) {
return (this.externallyManagedDestroyMethods != null &&
this.externallyManagedDestroyMethods.contains(destroyMethod));
}
}