Consistent fine-tuning of synchronized and concurrent data structures
In particular, avoiding synchronized Sets and Maps wherever possible (preferring a ConcurrentHashMap even instead of a synchronized Set) and specifying appropriate ConcurrentHashMap initial capacities (even if we end up choosing 16).
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -57,6 +57,7 @@ public abstract class BeanUtils {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(BeanUtils.class);
|
||||
|
||||
// using WeakHashMap as a Set
|
||||
private static final Map<Class<?>, Boolean> unknownEditorTypes =
|
||||
Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>());
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
@@ -70,14 +69,14 @@ public class CachedIntrospectionResults {
|
||||
* Set of ClassLoaders that this CachedIntrospectionResults class will always
|
||||
* accept classes from, even if the classes do not qualify as cache-safe.
|
||||
*/
|
||||
static final Set<ClassLoader> acceptedClassLoaders = Collections.synchronizedSet(new HashSet<ClassLoader>());
|
||||
static final Set<ClassLoader> acceptedClassLoaders = new HashSet<ClassLoader>();
|
||||
|
||||
/**
|
||||
* Map keyed by class containing CachedIntrospectionResults.
|
||||
* Needs to be a WeakHashMap with WeakReferences as values to allow
|
||||
* for proper garbage collection in case of multiple class loaders.
|
||||
*/
|
||||
static final Map<Class, Object> classCache = Collections.synchronizedMap(new WeakHashMap<Class, Object>());
|
||||
static final Map<Class, Object> classCache = new WeakHashMap<Class, Object>();
|
||||
|
||||
|
||||
/**
|
||||
@@ -94,7 +93,9 @@ public class CachedIntrospectionResults {
|
||||
*/
|
||||
public static void acceptClassLoader(ClassLoader classLoader) {
|
||||
if (classLoader != null) {
|
||||
acceptedClassLoaders.add(classLoader);
|
||||
synchronized (acceptedClassLoaders) {
|
||||
acceptedClassLoaders.add(classLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +138,10 @@ public class CachedIntrospectionResults {
|
||||
*/
|
||||
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
|
||||
CachedIntrospectionResults results;
|
||||
Object value = classCache.get(beanClass);
|
||||
Object value;
|
||||
synchronized (classCache) {
|
||||
value = classCache.get(beanClass);
|
||||
}
|
||||
if (value instanceof Reference) {
|
||||
Reference ref = (Reference) value;
|
||||
results = (CachedIntrospectionResults) ref.get();
|
||||
@@ -149,14 +153,18 @@ public class CachedIntrospectionResults {
|
||||
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
||||
isClassLoaderAccepted(beanClass.getClassLoader())) {
|
||||
results = new CachedIntrospectionResults(beanClass);
|
||||
classCache.put(beanClass, results);
|
||||
synchronized (classCache) {
|
||||
classCache.put(beanClass, results);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
||||
}
|
||||
results = new CachedIntrospectionResults(beanClass);
|
||||
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
||||
synchronized (classCache) {
|
||||
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
@@ -172,8 +180,10 @@ public class CachedIntrospectionResults {
|
||||
private static boolean isClassLoaderAccepted(ClassLoader classLoader) {
|
||||
// Iterate over array copy in order to avoid synchronization for the entire
|
||||
// ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator).
|
||||
ClassLoader[] acceptedLoaderArray =
|
||||
acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
|
||||
ClassLoader[] acceptedLoaderArray;
|
||||
synchronized (acceptedClassLoaders) {
|
||||
acceptedLoaderArray = acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
|
||||
}
|
||||
for (ClassLoader registeredLoader : acceptedLoaderArray) {
|
||||
if (isUnderneathClassLoader(classLoader, registeredLoader)) {
|
||||
return true;
|
||||
|
||||
@@ -119,10 +119,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
|
||||
new ConcurrentHashMap<Class<?>, Constructor<?>[]>();
|
||||
new ConcurrentHashMap<Class<?>, Constructor<?>[]>(64);
|
||||
|
||||
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
|
||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,8 +24,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@@ -85,7 +83,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||
|
||||
private transient final Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache =
|
||||
new ConcurrentHashMap<Class<?>, LifecycleMetadata>();
|
||||
new ConcurrentHashMap<Class<?>, LifecycleMetadata>(64);
|
||||
|
||||
|
||||
/**
|
||||
@@ -240,69 +238,57 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
*/
|
||||
private class LifecycleMetadata {
|
||||
|
||||
private final Set<LifecycleElement> initMethods;
|
||||
private final Class targetClass;
|
||||
|
||||
private final Set<LifecycleElement> destroyMethods;
|
||||
private final Collection<LifecycleElement> initMethods;
|
||||
|
||||
private final Collection<LifecycleElement> destroyMethods;
|
||||
|
||||
private volatile Set<LifecycleElement> checkedInitMethods;
|
||||
|
||||
private volatile Set<LifecycleElement> checkedDestroyMethods;
|
||||
|
||||
public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods,
|
||||
Collection<LifecycleElement> destroyMethods) {
|
||||
|
||||
if (!initMethods.isEmpty()) {
|
||||
this.initMethods = Collections.synchronizedSet(new LinkedHashSet<LifecycleElement>(initMethods.size()));
|
||||
for (LifecycleElement element : initMethods) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found init method on class [" + targetClass.getName() + "]: " + element);
|
||||
}
|
||||
this.initMethods.add(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.initMethods = Collections.emptySet();
|
||||
}
|
||||
|
||||
if (!destroyMethods.isEmpty()) {
|
||||
this.destroyMethods = Collections.synchronizedSet(new LinkedHashSet<LifecycleElement>(destroyMethods.size()));
|
||||
for (LifecycleElement element : destroyMethods) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found destroy method on class [" + targetClass.getName() + "]: " + element);
|
||||
}
|
||||
this.destroyMethods.add(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.destroyMethods = Collections.emptySet();
|
||||
}
|
||||
this.targetClass = targetClass;
|
||||
this.initMethods = initMethods;
|
||||
this.destroyMethods = destroyMethods;
|
||||
}
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
synchronized(this.initMethods) {
|
||||
for (Iterator<LifecycleElement> it = this.initMethods.iterator(); it.hasNext();) {
|
||||
String methodIdentifier = it.next().getIdentifier();
|
||||
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
}
|
||||
else {
|
||||
it.remove();
|
||||
Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<LifecycleElement>(this.initMethods.size());
|
||||
for (LifecycleElement element : this.initMethods) {
|
||||
String methodIdentifier = element.getIdentifier();
|
||||
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
|
||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||
checkedInitMethods.add(element);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
synchronized(this.destroyMethods) {
|
||||
for (Iterator<LifecycleElement> it = this.destroyMethods.iterator(); it.hasNext();) {
|
||||
String methodIdentifier = it.next().getIdentifier();
|
||||
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
}
|
||||
else {
|
||||
it.remove();
|
||||
Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<LifecycleElement>(this.destroyMethods.size());
|
||||
for (LifecycleElement element : this.destroyMethods) {
|
||||
String methodIdentifier = element.getIdentifier();
|
||||
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
|
||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||
checkedDestroyMethods.add(element);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.checkedInitMethods = checkedInitMethods;
|
||||
this.checkedDestroyMethods = checkedDestroyMethods;
|
||||
}
|
||||
|
||||
public void invokeInitMethods(Object target, String beanName) throws Throwable {
|
||||
if (!this.initMethods.isEmpty()) {
|
||||
Collection<LifecycleElement> initMethodsToIterate =
|
||||
(this.checkedInitMethods != null ? this.checkedInitMethods : this.initMethods);
|
||||
if (!initMethodsToIterate.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (LifecycleElement element : this.initMethods) {
|
||||
for (LifecycleElement element : initMethodsToIterate) {
|
||||
if (debug) {
|
||||
logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());
|
||||
}
|
||||
@@ -312,9 +298,11 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||
}
|
||||
|
||||
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
|
||||
if (!this.destroyMethods.isEmpty()) {
|
||||
Collection<LifecycleElement> destroyMethodsToIterate =
|
||||
(this.checkedDestroyMethods != null ? this.checkedDestroyMethods : this.destroyMethods);
|
||||
if (!destroyMethodsToIterate.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (LifecycleElement element : this.destroyMethods) {
|
||||
for (LifecycleElement element : destroyMethodsToIterate) {
|
||||
if (debug) {
|
||||
logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Member;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -50,42 +48,39 @@ public class InjectionMetadata {
|
||||
|
||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||
|
||||
private final Set<InjectedElement> injectedElements;
|
||||
private final Class targetClass;
|
||||
|
||||
private final Collection<InjectedElement> injectedElements;
|
||||
|
||||
private volatile Set<InjectedElement> checkedElements;
|
||||
|
||||
|
||||
public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
|
||||
if (!elements.isEmpty()) {
|
||||
this.injectedElements = Collections.synchronizedSet(new LinkedHashSet<InjectedElement>(elements.size()));
|
||||
for (InjectedElement element : elements) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Found injected element on class [" + targetClass.getName() + "]: " + element);
|
||||
}
|
||||
this.injectedElements.add(element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.injectedElements = Collections.emptySet();
|
||||
}
|
||||
this.targetClass = targetClass;
|
||||
this.injectedElements = elements;
|
||||
}
|
||||
|
||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||
synchronized (this.injectedElements) {
|
||||
for (Iterator<InjectedElement> it = this.injectedElements.iterator(); it.hasNext();) {
|
||||
Member member = it.next().getMember();
|
||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||
}
|
||||
else {
|
||||
it.remove();
|
||||
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
Member member = element.getMember();
|
||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||
checkedElements.add(element);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.checkedElements = checkedElements;
|
||||
}
|
||||
|
||||
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||
if (!this.injectedElements.isEmpty()) {
|
||||
Collection<InjectedElement> elementsToIterate =
|
||||
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
|
||||
if (!elementsToIterate.isEmpty()) {
|
||||
boolean debug = logger.isDebugEnabled();
|
||||
for (InjectedElement element : this.injectedElements) {
|
||||
for (InjectedElement element : elementsToIterate) {
|
||||
if (debug) {
|
||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -20,10 +20,9 @@ import java.beans.PropertyDescriptor;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValues;
|
||||
@@ -89,8 +88,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
/** Cache for validated bean names, skipping re-validation for the same bean */
|
||||
private final Set<String> validatedBeanNames = Collections.synchronizedSet(new HashSet<String>());
|
||||
/**
|
||||
* Cache for validated bean names, skipping re-validation for the same bean
|
||||
* (using a ConcurrentHashMap as a Set)
|
||||
*/
|
||||
private final Map<String, Boolean> validatedBeanNames = new ConcurrentHashMap<String, Boolean>(64);
|
||||
|
||||
|
||||
/**
|
||||
@@ -137,7 +139,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
|
||||
throws BeansException {
|
||||
|
||||
if (!this.validatedBeanNames.contains(beanName)) {
|
||||
if (!this.validatedBeanNames.containsKey(beanName)) {
|
||||
if (!shouldSkip(this.beanFactory, beanName)) {
|
||||
List<String> invalidProperties = new ArrayList<String>();
|
||||
for (PropertyDescriptor pd : pds) {
|
||||
@@ -149,7 +151,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
|
||||
}
|
||||
}
|
||||
this.validatedBeanNames.add(beanName);
|
||||
this.validatedBeanNames.put(beanName, Boolean.TRUE);
|
||||
}
|
||||
return pvs;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package org.springframework.beans.factory.config;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
@@ -71,8 +70,11 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||
|
||||
private boolean ignoreInvalidKeys = false;
|
||||
|
||||
/** Contains names of beans that have overrides */
|
||||
private Set<String> beanNames = Collections.synchronizedSet(new HashSet<String>());
|
||||
/**
|
||||
* Contains names of beans that have overrides
|
||||
* (using a ConcurrentHashMap as a Set)
|
||||
*/
|
||||
private Map<String, Boolean> beanNames = new ConcurrentHashMap<String, Boolean>(16);
|
||||
|
||||
|
||||
/**
|
||||
@@ -128,7 +130,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||
}
|
||||
String beanName = key.substring(0, separatorIndex);
|
||||
String beanProperty = key.substring(separatorIndex+1);
|
||||
this.beanNames.add(beanName);
|
||||
this.beanNames.put(beanName, Boolean.TRUE);
|
||||
applyPropertyValue(factory, beanName, beanProperty, value);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Property '" + key + "' set to value [" + value + "]");
|
||||
@@ -159,7 +161,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||
* the named bean
|
||||
*/
|
||||
public boolean hasPropertyOverridesFor(String beanName) {
|
||||
return this.beanNames.contains(beanName);
|
||||
return this.beanNames.containsKey(beanName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -145,11 +145,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||
|
||||
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
|
||||
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
|
||||
new ConcurrentHashMap<String, BeanWrapper>();
|
||||
new ConcurrentHashMap<String, BeanWrapper>(16);
|
||||
|
||||
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
|
||||
private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
|
||||
new ConcurrentHashMap<Class, PropertyDescriptor[]>();
|
||||
new ConcurrentHashMap<Class, PropertyDescriptor[]>(64);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,6 @@ import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
@@ -151,17 +150,20 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
private boolean hasDestructionAwareBeanPostProcessors;
|
||||
|
||||
/** Map from scope identifier String to corresponding Scope */
|
||||
private final Map<String, Scope> scopes = new HashMap<String, Scope>();
|
||||
private final Map<String, Scope> scopes = new HashMap<String, Scope>(8);
|
||||
|
||||
/** Security context used when running with a SecurityManager */
|
||||
private SecurityContextProvider securityContextProvider;
|
||||
|
||||
/** Map from bean name to merged RootBeanDefinition */
|
||||
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
|
||||
new ConcurrentHashMap<String, RootBeanDefinition>();
|
||||
new ConcurrentHashMap<String, RootBeanDefinition>(64);
|
||||
|
||||
/** Names of beans that have already been created at least once */
|
||||
private final Set<String> alreadyCreated = Collections.synchronizedSet(new HashSet<String>());
|
||||
/**
|
||||
* Names of beans that have already been created at least once
|
||||
* (using a ConcurrentHashMap as a Set)
|
||||
*/
|
||||
private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);
|
||||
|
||||
/** Names of beans that are currently in creation */
|
||||
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
|
||||
@@ -1372,7 +1374,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @param beanName the name of the bean
|
||||
*/
|
||||
protected void markBeanAsCreated(String beanName) {
|
||||
this.alreadyCreated.add(beanName);
|
||||
this.alreadyCreated.put(beanName, Boolean.TRUE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1383,7 +1385,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* at this point already
|
||||
*/
|
||||
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
|
||||
return this.alreadyCreated.contains(beanName);
|
||||
return this.alreadyCreated.containsKey(beanName);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1393,7 +1395,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
* @return <code>true</code> if actually removed, <code>false</code> otherwise
|
||||
*/
|
||||
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
|
||||
if (!this.alreadyCreated.contains(beanName)) {
|
||||
if (!this.alreadyCreated.containsKey(beanName)) {
|
||||
removeSingleton(beanName);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
|
||||
/** Map from serialized id to factory instance */
|
||||
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
|
||||
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>();
|
||||
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
|
||||
|
||||
/** Optional id for this factory, for serialization purposes */
|
||||
private String serializationId;
|
||||
@@ -127,16 +127,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
|
||||
|
||||
/** Map from dependency type to corresponding autowired value */
|
||||
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>();
|
||||
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
|
||||
|
||||
/** Map of bean definition objects, keyed by bean name */
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
|
||||
|
||||
/** Map of singleton bean names keyed by bean class */
|
||||
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>();
|
||||
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||
|
||||
/** Map of non-singleton bean names keyed by bean class */
|
||||
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>();
|
||||
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||
|
||||
/** List of bean definition names, in registration order */
|
||||
private final List<String> beanDefinitionNames = new ArrayList<String>();
|
||||
|
||||
@@ -81,22 +81,22 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
/** Cache of singleton objects: bean name --> bean instance */
|
||||
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
|
||||
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
|
||||
|
||||
/** Cache of singleton factories: bean name --> ObjectFactory */
|
||||
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>();
|
||||
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
|
||||
|
||||
/** Cache of early singleton objects: bean name --> bean instance */
|
||||
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>();
|
||||
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
|
||||
|
||||
/** Set of registered singletons, containing the bean names in registration order */
|
||||
private final Set<String> registeredSingletons = new LinkedHashSet<String>(16);
|
||||
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
|
||||
|
||||
/** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */
|
||||
private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>();
|
||||
private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);
|
||||
|
||||
/** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */
|
||||
private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>();
|
||||
private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);
|
||||
|
||||
/** List of suppressed Exceptions, available for associating related causes */
|
||||
private Set<Exception> suppressedExceptions;
|
||||
@@ -108,13 +108,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
|
||||
|
||||
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
|
||||
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
||||
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
|
||||
|
||||
/** Map between dependent bean names: bean name --> Set of dependent bean names */
|
||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
|
||||
|
||||
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
|
||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
|
||||
|
||||
|
||||
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -43,7 +43,7 @@ import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
|
||||
|
||||
/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */
|
||||
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();
|
||||
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -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.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.MutablePropertyValues;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -48,11 +47,14 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
|
||||
private final Set<Member> externallyManagedConfigMembers = Collections.synchronizedSet(new HashSet<Member>(0));
|
||||
// using a ConcurrentHashMap as a Set
|
||||
private final Map<Member, Boolean> externallyManagedConfigMembers = new ConcurrentHashMap<Member, Boolean>(0);
|
||||
|
||||
private final Set<String> externallyManagedInitMethods = Collections.synchronizedSet(new HashSet<String>(0));
|
||||
// using a ConcurrentHashMap as a Set
|
||||
private final Map<String, Boolean> externallyManagedInitMethods = new ConcurrentHashMap<String, Boolean>(0);
|
||||
|
||||
private final Set<String> externallyManagedDestroyMethods = Collections.synchronizedSet(new HashSet<String>(0));
|
||||
// using a ConcurrentHashMap as a Set
|
||||
private final Map<String, Boolean> externallyManagedDestroyMethods = new ConcurrentHashMap<String, Boolean>(0);
|
||||
|
||||
private BeanDefinitionHolder decoratedDefinition;
|
||||
|
||||
@@ -277,27 +279,27 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||
|
||||
|
||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||
this.externallyManagedConfigMembers.add(configMember);
|
||||
this.externallyManagedConfigMembers.put(configMember, Boolean.TRUE);
|
||||
}
|
||||
|
||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||
return this.externallyManagedConfigMembers.contains(configMember);
|
||||
return this.externallyManagedConfigMembers.containsKey(configMember);
|
||||
}
|
||||
|
||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||
this.externallyManagedInitMethods.add(initMethod);
|
||||
this.externallyManagedInitMethods.put(initMethod, Boolean.TRUE);
|
||||
}
|
||||
|
||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||
return this.externallyManagedInitMethods.contains(initMethod);
|
||||
return this.externallyManagedInitMethods.containsKey(initMethod);
|
||||
}
|
||||
|
||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
this.externallyManagedDestroyMethods.add(destroyMethod);
|
||||
this.externallyManagedDestroyMethods.put(destroyMethod, Boolean.TRUE);
|
||||
}
|
||||
|
||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||
return this.externallyManagedDestroyMethods.contains(destroyMethod);
|
||||
return this.externallyManagedDestroyMethods.containsKey(destroyMethod);
|
||||
}
|
||||
|
||||
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -37,7 +37,7 @@ import org.springframework.util.StringUtils;
|
||||
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
|
||||
|
||||
/** Map of bean definition objects, keyed by bean name */
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
|
||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
|
||||
|
||||
|
||||
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -155,7 +155,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded NamespaceHandler mappings: " + mappings);
|
||||
}
|
||||
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>();
|
||||
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
|
||||
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
|
||||
this.handlerMappings = handlerMappings;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2009 the original author or authors.
|
||||
* Copyright 2002-2012 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.
|
||||
@@ -145,7 +145,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Loaded schema mappings: " + mappings);
|
||||
}
|
||||
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>();
|
||||
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
|
||||
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
|
||||
this.schemaMappings = schemaMappings;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user