提交 b9df7d68 编写于 作者: J Juergen Hoeller

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).
上级 a2f8902b
......@@ -46,7 +46,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
*/
private int order = Ordered.LOWEST_PRECEDENCE;
private final Map<String, Boolean> eligibleBeans = new ConcurrentHashMap<String, Boolean>();
private final Map<String, Boolean> eligibleBeans = new ConcurrentHashMap<String, Boolean>(64);
public void setBeanClassLoader(ClassLoader beanClassLoader) {
......
/*
* 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.
......@@ -20,11 +20,8 @@ import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.aop.Advice;
......@@ -136,15 +133,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
private BeanFactory beanFactory;
private final Set<Object> targetSourcedBeans = Collections.synchronizedSet(new HashSet<Object>());
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(64);
private final Set<Object> earlyProxyReferences = Collections.synchronizedSet(new HashSet<Object>());
// using a ConcurrentHashMap as a Set
private final Map<String, Boolean> targetSourcedBeans = new ConcurrentHashMap<String, Boolean>(16);
private final Set<Object> advisedBeans = Collections.synchronizedSet(new HashSet<Object>());
// using a ConcurrentHashMap as a Set
private final Map<Object, Boolean> earlyProxyReferences = new ConcurrentHashMap<Object, Boolean>(16);
private final Set<Object> nonAdvisedBeans = Collections.synchronizedSet(new HashSet<Object>());
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>();
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16);
/**
......@@ -264,19 +261,19 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.add(cacheKey);
this.earlyProxyReferences.put(cacheKey, Boolean.TRUE);
return wrapIfNecessary(bean, beanName, cacheKey);
}
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!this.targetSourcedBeans.contains(cacheKey)) {
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
if (!this.targetSourcedBeans.containsKey(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey);
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
......@@ -286,7 +283,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
this.targetSourcedBeans.add(beanName);
this.targetSourcedBeans.put(beanName, Boolean.TRUE);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
......@@ -318,7 +315,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
......@@ -344,27 +341,27 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (this.targetSourcedBeans.contains(beanName)) {
if (this.targetSourcedBeans.containsKey(beanName)) {
return bean;
}
if (this.nonAdvisedBeans.contains(cacheKey)) {
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.nonAdvisedBeans.add(cacheKey);
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.add(cacheKey);
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.nonAdvisedBeans.add(cacheKey);
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
......
/*
* 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.
......@@ -16,7 +16,6 @@
package org.springframework.aop.target;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
......@@ -62,7 +61,7 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
/**
* Set of managed targets, enabling us to keep track of the targets we've created.
*/
private final Set<Object> targetSet = Collections.synchronizedSet(new HashSet<Object>());
private final Set<Object> targetSet = new HashSet<Object>();
private int invocationCount;
......@@ -85,7 +84,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
// Associate target with ThreadLocal.
target = newPrototypeInstance();
this.targetInThread.set(target);
this.targetSet.add(target);
synchronized (this.targetSet) {
this.targetSet.add(target);
}
}
else {
++this.hitCount;
......@@ -119,7 +120,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
}
public int getObjectCount() {
return this.targetSet.size();
synchronized (this.targetSet) {
return this.targetSet.size();
}
}
......
/*
* 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);
}
......
/*
* 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;
}
......
/*
* 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 {
......
/*
* 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) {
......
/*
* 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)
......
/*
* 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;
}
......
/*
* 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;
}
......
......@@ -56,7 +56,7 @@ public class ConcurrentMapCache implements Cache {
* @param name the name of the cache
*/
public ConcurrentMapCache(String name) {
this(name, new ConcurrentHashMap<Object, Object>(), true);
this(name, new ConcurrentHashMap<Object, Object>(256), true);
}
/**
......@@ -65,7 +65,7 @@ public class ConcurrentMapCache implements Cache {
* @param allowNullValues whether to accept and convert null values for this cache
*/
public ConcurrentMapCache(String name, boolean allowNullValues) {
this(name, new ConcurrentHashMap<Object, Object>(), allowNullValues);
this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues);
}
/**
......
/*
* 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.
......@@ -36,7 +36,7 @@ import org.springframework.cache.CacheManager;
*/
public class ConcurrentMapCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private boolean dynamic = true;
......
/*
* 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.
......@@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
......@@ -48,6 +49,7 @@ import org.springframework.util.ObjectUtils;
* configurable.
*
* @author Costin Leau
* @author Juergen Hoeller
* @since 3.1
*/
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
......@@ -70,7 +72,8 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
* <p>As this base class is not marked Serializable, the cache will be recreated
* after serialization - provided that the concrete subclass is Serializable.
*/
final Map<Object, Collection<CacheOperation>> attributeCache = new ConcurrentHashMap<Object, Collection<CacheOperation>>();
final Map<Object, Collection<CacheOperation>> attributeCache =
new ConcurrentHashMap<Object, Collection<CacheOperation>>(1024);
/**
......
/*
* 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.
......@@ -39,16 +39,16 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
*/
class ExpressionEvaluator {
private SpelExpressionParser parser = new SpelExpressionParser();
private final SpelExpressionParser parser = new SpelExpressionParser();
// shared param discoverer since it caches data internally
private ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
private final ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
private Map<String, Expression> conditionCache = new ConcurrentHashMap<String, Expression>();
private final Map<String, Expression> conditionCache = new ConcurrentHashMap<String, Expression>(64);
private Map<String, Expression> keyCache = new ConcurrentHashMap<String, Expression>();
private final Map<String, Expression> keyCache = new ConcurrentHashMap<String, Expression>(64);
private Map<String, Method> targetMethodCache = new ConcurrentHashMap<String, Method>();
private final Map<String, Method> targetMethodCache = new ConcurrentHashMap<String, Method>(64);
public EvaluationContext createEvaluationContext(
......
......@@ -29,9 +29,8 @@ import org.springframework.cache.CacheManager;
import org.springframework.util.Assert;
/**
* Abstract base class implementing the common {@link CacheManager}
* methods. Useful for 'static' environments where the backing caches do
* not change.
* Abstract base class implementing the common {@link CacheManager} methods.
* Useful for 'static' environments where the backing caches do not change.
*
* @author Costin Leau
* @author Juergen Hoeller
......@@ -39,9 +38,9 @@ import org.springframework.util.Assert;
*/
public abstract class AbstractCacheManager implements CacheManager, InitializingBean {
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
private Set<String> cacheNames = new LinkedHashSet<String>();
private Set<String> cacheNames = new LinkedHashSet<String>(16);
public void afterPropertiesSet() {
......
/*
* Copyright 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.
......@@ -39,8 +39,36 @@ import org.springframework.cache.CacheManager;
*/
public class NoOpCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
private Set<String> names = new LinkedHashSet<String>();
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(16);
private final Set<String> cacheNames = new LinkedHashSet<String>(16);
/**
* This implementation always returns a {@link Cache} implementation that will not store items.
* Additionally, the request cache will be remembered by the manager for consistency.
*/
public Cache getCache(String name) {
Cache cache = this.caches.get(name);
if (cache == null) {
this.caches.putIfAbsent(name, new NoOpCache(name));
synchronized (this.cacheNames) {
this.cacheNames.add(name);
}
}
return this.caches.get(name);
}
/**
* This implementation returns the name of the caches previously requested.
*/
public Collection<String> getCacheNames() {
synchronized (this.cacheNames) {
return Collections.unmodifiableSet(this.cacheNames);
}
}
private static class NoOpCache implements Cache {
......@@ -61,7 +89,7 @@ public class NoOpCacheManager implements CacheManager {
}
public String getName() {
return name;
return this.name;
}
public Object getNativeCache() {
......@@ -72,30 +100,4 @@ public class NoOpCacheManager implements CacheManager {
}
}
/**
* {@inheritDoc}
*
* This implementation always returns a {@link Cache} implementation that will not
* store items. Additionally, the request cache will be remembered by the manager for consistency.
*/
public Cache getCache(String name) {
Cache cache = caches.get(name);
if (cache == null) {
caches.putIfAbsent(name, new NoOpCache(name));
synchronized (names) {
names.add(name);
}
}
return caches.get(name);
}
/**
* {@inheritDoc}
*
* This implementation returns the name of the caches previously requested.
*/
public Collection<String> getCacheNames() {
return Collections.unmodifiableSet(names);
}
}
......@@ -178,7 +178,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private transient BeanFactory beanFactory;
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
/**
......@@ -513,10 +513,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
protected boolean shareable = true;
private volatile boolean cached = false;
private volatile Object cachedFieldValue;
public ResourceElement(Member member, PropertyDescriptor pd) {
super(member, pd);
}
......
......@@ -53,7 +53,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>();
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
private BeanFactory beanFactory;
......
/*
* 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.
......@@ -60,10 +60,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
private ExpressionParser expressionParser = new SpelExpressionParser();
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>(256);
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(8);
private final ParserContext beanExpressionParserContext = new ParserContext() {
public boolean isTemplate() {
......
......@@ -1387,7 +1387,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/
private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor {
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>();
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>(64);
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanDefinition.isSingleton()) {
......
......@@ -53,10 +53,10 @@ public class FormattingConversionService extends GenericConversionService
private StringValueResolver embeddedValueResolver;
private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters =
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>();
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
private final Map<AnnotationConverterKey, GenericConverter> cachedParsers =
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>();
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
public void setEmbeddedValueResolver(StringValueResolver resolver) {
......@@ -214,11 +214,14 @@ public class FormattingConversionService extends GenericConversionService
return sourceType.hasAnnotation(annotationType);
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
AnnotationConverterKey converterKey = new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType());
AnnotationConverterKey converterKey =
new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType());
GenericConverter converter = cachedPrinters.get(converterKey);
if (converter == null) {
Printer<?> printer = annotationFormatterFactory.getPrinter(converterKey.getAnnotation(), converterKey.getFieldType());
Printer<?> printer = annotationFormatterFactory.getPrinter(
converterKey.getAnnotation(), converterKey.getFieldType());
converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this);
cachedPrinters.put(converterKey, converter);
}
......@@ -226,7 +229,8 @@ public class FormattingConversionService extends GenericConversionService
}
public String toString() {
return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + String.class.getName() + ": " + annotationFormatterFactory;
return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " +
String.class.getName() + ": " + annotationFormatterFactory;
}
}
......@@ -254,11 +258,14 @@ public class FormattingConversionService extends GenericConversionService
return targetType.hasAnnotation(annotationType);
}
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
AnnotationConverterKey converterKey = new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType());
AnnotationConverterKey converterKey =
new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType());
GenericConverter converter = cachedParsers.get(converterKey);
if (converter == null) {
Parser<?> parser = annotationFormatterFactory.getParser(converterKey.getAnnotation(), converterKey.getFieldType());
Parser<?> parser = annotationFormatterFactory.getParser(
converterKey.getAnnotation(), converterKey.getFieldType());
converter = new ParserConverter(fieldType, parser, FormattingConversionService.this);
cachedParsers.put(converterKey, converter);
}
......@@ -266,7 +273,8 @@ public class FormattingConversionService extends GenericConversionService
}
public String toString() {
return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName() + ": " + annotationFormatterFactory;
return String.class.getName() + " -> @" + annotationType.getName() + " " +
fieldType.getName() + ": " + annotationFormatterFactory;
}
}
......
......@@ -42,10 +42,9 @@ import org.springframework.util.ClassUtils;
* information in the method attributes to discover parameter names. Returns
* <code>null</code> if the class file was compiled without debug information.
*
* <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer
* instance caches the ASM discovered information for each introspected Class, in a
* thread-safe manner. It is recommended to reuse discoverer instances
* as far as possible.
* <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer instance
* caches the ASM discovered information for each introspected Class, in a thread-safe
* manner. It is recommended to reuse ParameterNameDiscoverer instances as far as possible.
*
* @author Adrian Colyer
* @author Costin Leau
......@@ -62,7 +61,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
// the cache uses a nested index (value is a map) to keep the top level cache relatively small in size
private final Map<Class<?>, Map<Member, String[]>> parameterNamesCache =
new ConcurrentHashMap<Class<?>, Map<Member, String[]>>();
new ConcurrentHashMap<Class<?>, Map<Member, String[]>>(32);
public String[] getParameterNames(Method method) {
......@@ -111,7 +110,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
}
try {
ClassReader classReader = new ClassReader(is);
Map<Member, String[]> map = new ConcurrentHashMap<Member, String[]>();
Map<Member, String[]> map = new ConcurrentHashMap<Member, String[]>(32);
classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);
return map;
}
......
/*
* 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.
......@@ -38,7 +38,7 @@ import org.springframework.util.StringValueResolver;
public class SimpleAliasRegistry implements AliasRegistry {
/** Map from alias to canonical name */
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>();
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
public void registerAlias(String name, String alias) {
......
......@@ -74,7 +74,7 @@ public class GenericConversionService implements ConfigurableConversionService {
private final Converters converters = new Converters();
private final Map<ConverterCacheKey, GenericConverter> converterCache =
new ConcurrentHashMap<ConverterCacheKey, GenericConverter>();
new ConcurrentHashMap<ConverterCacheKey, GenericConverter>(64);
// implementing ConverterRegistry
......@@ -182,8 +182,8 @@ public class GenericConversionService implements ConfigurableConversionService {
* @param targetType the target type
* @return the converted value
* @throws ConversionException if a conversion exception occurred
* @throws IllegalArgumentException if targetType is null
* @throws IllegalArgumentException if sourceType is null but source is not null
* @throws IllegalArgumentException if targetType is null,
* or sourceType is null but source is not null
*/
public Object convert(Object source, TypeDescriptor targetType) {
return convert(source, TypeDescriptor.forObject(source), targetType);
......@@ -480,7 +480,6 @@ public class GenericConversionService implements ConfigurableConversionService {
* @param sourceType the source type
* @param targetType the target type
* @return a {@link GenericConverter} or <tt>null</tt>
* @see #getTypeHierarchy(Class)
*/
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
// Search the full type hierarchy
......
......@@ -46,11 +46,11 @@ import org.springframework.util.StringUtils;
*/
public class ReflectivePropertyAccessor implements PropertyAccessor {
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>();
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>();
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
private final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>();
private final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>(64);
/**
......@@ -86,7 +86,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
Field field = findField(name, type, target);
if (field != null) {
TypeDescriptor typeDescriptor = new TypeDescriptor(field);
this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor));
this.readerCache.put(cacheKey, new InvokerPair(field, typeDescriptor));
this.typeDescriptorCache.put(cacheKey, typeDescriptor);
return true;
}
......@@ -264,15 +264,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
return TypeDescriptor.valueOf(Integer.TYPE);
}
CacheKey cacheKey = new CacheKey(type, name);
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
if (typeDescriptor == null) {
// attempt to populate the cache entry
try {
if (canRead(context, target, name)) {
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
}
else if (canWrite(context, target, name)) {
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
}
}
catch (AccessException ex) {
......
/*
* 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.
......@@ -60,7 +60,7 @@ public class JndiDestinationResolver extends JndiLocatorSupport implements Cachi
private DestinationResolver dynamicDestinationResolver = new DynamicDestinationResolver();
private final Map<String, Destination> destinationCache = new ConcurrentHashMap<String, Destination>();
private final Map<String, Destination> destinationCache = new ConcurrentHashMap<String, Destination>(16);
/**
......
/*
* 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.
......@@ -16,9 +16,8 @@
package org.springframework.orm.hibernate3;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.FlushMode;
import org.hibernate.Session;
......@@ -44,10 +43,10 @@ public class SessionHolder extends ResourceHolderSupport {
private static final Object DEFAULT_KEY = new Object();
/**
* This Map needs to be synchronized because there might be multi-threaded
* This Map needs to be concurrent because there might be multi-threaded
* access in the case of JTA with remote transaction propagation.
*/
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
private final Map<Object, Session> sessionMap = new ConcurrentHashMap<Object, Session>(1);
private Transaction transaction;
......@@ -89,12 +88,10 @@ public class SessionHolder extends ResourceHolderSupport {
}
public Session getAnySession() {
synchronized (this.sessionMap) {
if (!this.sessionMap.isEmpty()) {
return this.sessionMap.values().iterator().next();
}
return null;
if (!this.sessionMap.isEmpty()) {
return this.sessionMap.values().iterator().next();
}
return null;
}
public void addSession(Session session) {
......@@ -120,10 +117,8 @@ public class SessionHolder extends ResourceHolderSupport {
}
public boolean doesNotHoldNonDefaultSession() {
synchronized (this.sessionMap) {
return this.sessionMap.isEmpty() ||
(this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
}
return this.sessionMap.isEmpty() ||
(this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
}
......
/*
* 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.
......@@ -182,10 +182,10 @@ public class PersistenceAnnotationBeanPostProcessor
private transient ListableBeanFactory beanFactory;
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
private final Map<Object, EntityManager> extendedEntityManagersToClose =
new ConcurrentHashMap<Object, EntityManager>();
new ConcurrentHashMap<Object, EntityManager>(16);
/**
......
/*
* 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.
......@@ -18,27 +18,26 @@ package org.springframework.mock.jndi;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NamingException;
import org.springframework.jndi.JndiTemplate;
/**
* Simple extension of the JndiTemplate class that always returns a given
* object. Very useful for testing. Effectively a mock object.
*
* Simple extension of the JndiTemplate class that always returns a given object.
*
* <p>Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson
* @author Juergen Hoeller
*/
public class ExpectedLookupTemplate extends JndiTemplate {
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>();
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>(16);
/**
* Construct a new JndiTemplate that will always return given objects for
* given names. To be populated through <code>addObject</code> calls.
*
* @see #addObject(String, Object)
*/
public ExpectedLookupTemplate() {
......@@ -47,7 +46,6 @@ public class ExpectedLookupTemplate extends JndiTemplate {
/**
* Construct a new JndiTemplate that will always return the given object,
* but honour only requests for the given name.
*
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
......@@ -56,9 +54,7 @@ public class ExpectedLookupTemplate extends JndiTemplate {
}
/**
* Add the given object to the list of JNDI objects that this template will
* expose.
*
* Add the given object to the list of JNDI objects that this template will expose.
* @param name the name the client is expected to look up
* @param object the object that will be returned
*/
......
......@@ -44,7 +44,8 @@ class ContextCache {
/**
* Map of context keys to Spring ApplicationContext instances.
*/
private final Map<MergedContextConfiguration, ApplicationContext> contextMap = new ConcurrentHashMap<MergedContextConfiguration, ApplicationContext>();
private final Map<MergedContextConfiguration, ApplicationContext> contextMap =
new ConcurrentHashMap<MergedContextConfiguration, ApplicationContext>(64);
private int hitCount;
......@@ -69,7 +70,6 @@ class ContextCache {
/**
* Return whether there is a cached context for the given key.
*
* @param key the context key (never <code>null</code>)
*/
boolean contains(MergedContextConfiguration key) {
......@@ -79,10 +79,8 @@ class ContextCache {
/**
* Obtain a cached ApplicationContext for the given key.
*
* <p>The {@link #getHitCount() hit} and {@link #getMissCount() miss}
* counts will be updated accordingly.
*
* @param key the context key (never <code>null</code>)
* @return the corresponding ApplicationContext instance,
* or <code>null</code> if not found in the cache.
......@@ -135,7 +133,6 @@ class ContextCache {
/**
* Explicitly add an ApplicationContext instance to the cache under the given key.
*
* @param key the context key (never <code>null</code>)
* @param context the ApplicationContext instance (never <code>null</code>)
*/
......@@ -147,7 +144,6 @@ class ContextCache {
/**
* Remove the context with the given key.
*
* @param key the context key (never <code>null</code>)
* @return the corresponding ApplicationContext instance, or <code>null</code>
* if not found in the cache.
......@@ -162,11 +158,9 @@ class ContextCache {
* {@link #remove removing} the context from the cache and explicitly
* {@link ConfigurableApplicationContext#close() closing} it if it is an
* instance of {@link ConfigurableApplicationContext}.
*
* <p>Generally speaking, you would only call this method if you change the
* state of a singleton bean, potentially affecting future interaction with
* the context.
*
* @param key the context key (never <code>null</code>)
* @see #remove
*/
......@@ -192,11 +186,8 @@ class ContextCache {
* as the {@link #hitCount hit} and {@link #missCount miss} counts.
*/
public String toString() {
return new ToStringCreator(this)//
.append("size", size())//
.append("hitCount", getHitCount())//
.append("missCount", getMissCount())//
.toString();
return new ToStringCreator(this).append("size", size()).append("hitCount", getHitCount()).
append("missCount", getMissCount()).toString();
}
}
......@@ -21,12 +21,13 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
......@@ -111,7 +112,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource();
private final Map<Method, TransactionContext> transactionContextCache =
Collections.synchronizedMap(new IdentityHashMap<Method, TransactionContext>());
new ConcurrentHashMap<Method, TransactionContext>(8);
private TransactionConfigurationAttributes configurationAttributes;
......
/*
* 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.
......@@ -69,7 +69,7 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran
* <p>As this base class is not marked Serializable, the cache will be recreated
* after serialization - provided that the concrete subclass is Serializable.
*/
final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<Object, TransactionAttribute>();
final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<Object, TransactionAttribute>(1024);
/**
......
/*
* 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.
......@@ -27,19 +27,19 @@ import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.util.Assert;
/**
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} that
* use JAXB2. Creates {@link JAXBContext} object lazily.
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters}
* that use JAXB2. Creates {@link JAXBContext} object lazily.
*
* @author Arjen Poutsma
* @since 3.0
*/
public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHttpMessageConverter<T> {
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>(64);
/**
* Creates a new {@link Marshaller} for the given class.
*
* Create a new {@link Marshaller} for the given class.
* @param clazz the class to create the marshaller for
* @return the {@code Marshaller}
* @throws HttpMessageConversionException in case of JAXB errors
......@@ -56,8 +56,7 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt
}
/**
* Creates a new {@link Unmarshaller} for the given class.
*
* Create a new {@link Unmarshaller} for the given class.
* @param clazz the class to create the unmarshaller for
* @return the {@code Unmarshaller}
* @throws HttpMessageConversionException in case of JAXB errors
......@@ -74,19 +73,18 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt
}
/**
* Returns a {@link JAXBContext} for the given class.
*
* Return a {@link JAXBContext} for the given class.
* @param clazz the class to return the context for
* @return the {@code JAXBContext}
* @throws HttpMessageConversionException in case of JAXB errors
*/
protected final JAXBContext getJaxbContext(Class clazz) {
Assert.notNull(clazz, "'clazz' must not be null");
JAXBContext jaxbContext = jaxbContexts.get(clazz);
JAXBContext jaxbContext = this.jaxbContexts.get(clazz);
if (jaxbContext == null) {
try {
jaxbContext = JAXBContext.newInstance(clazz);
jaxbContexts.putIfAbsent(clazz, jaxbContext);
this.jaxbContexts.putIfAbsent(clazz, jaxbContext);
}
catch (JAXBException ex) {
throw new HttpMessageConversionException(
......
......@@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.accept;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
......@@ -37,11 +38,12 @@ import org.springframework.util.MultiValueMap;
*/
public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver {
private final ConcurrentMap<String, MediaType> mediaTypes = new ConcurrentHashMap<String, MediaType>();
private final ConcurrentMap<String, MediaType> mediaTypes = new ConcurrentHashMap<String, MediaType>(64);
private final MultiValueMap<MediaType, String> fileExtensions = new LinkedMultiValueMap<MediaType, String>();
private final List<String> allFileExtensions = new ArrayList<String>();
private final List<String> allFileExtensions = new LinkedList<String>();
/**
* Create an instance with the given mappings between extensions and media types.
......@@ -89,4 +91,4 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten
}
}
}
\ No newline at end of file
}
/*
* 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.
......@@ -19,10 +19,11 @@ package org.springframework.web.bind.annotation.support;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.annotation.AnnotationUtils;
......@@ -64,7 +65,8 @@ public class HandlerMethodResolver {
private final Set<Class> sessionAttributeTypes = new HashSet<Class>();
private final Set<String> actualSessionAttributeNames = Collections.synchronizedSet(new HashSet<String>(4));
// using a ConcurrentHashMap as a Set
private final Map<String, Boolean> actualSessionAttributeNames = new ConcurrentHashMap<String, Boolean>(4);
/**
......@@ -152,7 +154,7 @@ public class HandlerMethodResolver {
public boolean isSessionAttribute(String attrName, Class attrType) {
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
this.actualSessionAttributeNames.add(attrName);
this.actualSessionAttributeNames.put(attrName, Boolean.TRUE);
return true;
}
else {
......@@ -161,7 +163,7 @@ public class HandlerMethodResolver {
}
public Set<String> getActualSessionAttributeNames() {
return this.actualSessionAttributeNames;
return this.actualSessionAttributeNames.keySet();
}
}
......@@ -62,7 +62,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
private final BeanExpressionContext expressionContext;
private Map<MethodParameter, NamedValueInfo> namedValueInfoCache =
new ConcurrentHashMap<MethodParameter, NamedValueInfo>();
new ConcurrentHashMap<MethodParameter, NamedValueInfo>(256);
/**
* @param beanFactory a bean factory to use for resolving ${...} placeholder
......@@ -80,11 +80,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
throws Exception {
Class<?> paramType = parameter.getParameterType();
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
if (arg == null) {
if (namedValueInfo.defaultValue != null) {
arg = resolveDefaultValue(namedValueInfo.defaultValue);
......@@ -121,7 +119,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
/**
* Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically
* retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}.
*
* @param parameter the method parameter
* @return the named value information
*/
......@@ -146,7 +143,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
* @param name the name of the value being resolved
* @param parameter the method parameter to resolve to an argument value
* @param request the current request
*
* @return the resolved argument. May be {@code null}
* @throws Exception in case of errors
*/
......@@ -203,9 +199,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
*/
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
}
/**
* Represents the information about a named value, including name, whether it's required and a default value.
*/
......@@ -223,4 +219,5 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
this.defaultValue = defaultValue;
}
}
}
/*
* 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.
......@@ -46,10 +46,10 @@ public class ExceptionHandlerMethodResolver {
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
private final Map<Class<? extends Throwable>, Method> mappedMethods =
new ConcurrentHashMap<Class<? extends Throwable>, Method>();
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache =
new ConcurrentHashMap<Class<? extends Throwable>, Method>();
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
/**
* A constructor that finds {@link ExceptionHandler} methods in the given type.
......
......@@ -17,11 +17,11 @@
package org.springframework.web.method.annotation;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert;
......@@ -50,10 +50,12 @@ public class SessionAttributesHandler {
private final Set<Class<?>> attributeTypes = new HashSet<Class<?>>();
private final Set<String> knownAttributeNames = Collections.synchronizedSet(new HashSet<String>(4));
// using a ConcurrentHashMap as a Set
private final Map<String, Boolean> knownAttributeNames = new ConcurrentHashMap<String, Boolean>(4);
private final SessionAttributeStore sessionAttributeStore;
/**
* Create a new instance for a controller type. Session attribute names and
* types are extracted from the {@code @SessionAttributes} annotation, if
......@@ -71,7 +73,9 @@ public class SessionAttributesHandler {
this.attributeTypes.addAll(Arrays.<Class<?>>asList(annotation.types()));
}
this.knownAttributeNames.addAll(this.attributeNames);
for (String attributeName : this.attributeNames) {
this.knownAttributeNames.put(attributeName, Boolean.TRUE);
}
}
/**
......@@ -96,7 +100,7 @@ public class SessionAttributesHandler {
public boolean isHandlerSessionAttribute(String attributeName, Class<?> attributeType) {
Assert.notNull(attributeName, "Attribute name must not be null");
if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) {
this.knownAttributeNames.add(attributeName);
this.knownAttributeNames.put(attributeName, Boolean.TRUE);
return true;
}
else {
......@@ -130,7 +134,7 @@ public class SessionAttributesHandler {
*/
public Map<String, Object> retrieveAttributes(WebRequest request) {
Map<String, Object> attributes = new HashMap<String, Object>();
for (String name : this.knownAttributeNames) {
for (String name : this.knownAttributeNames.keySet()) {
Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
if (value != null) {
attributes.put(name, value);
......@@ -146,7 +150,7 @@ public class SessionAttributesHandler {
* @param request the current request
*/
public void cleanupAttributes(WebRequest request) {
for (String attributeName : this.knownAttributeNames) {
for (String attributeName : this.knownAttributeNames.keySet()) {
this.sessionAttributeStore.cleanupAttribute(request, attributeName);
}
}
......@@ -161,4 +165,4 @@ public class SessionAttributesHandler {
return this.sessionAttributeStore.retrieveAttribute(request, attributeName);
}
}
\ No newline at end of file
}
......@@ -16,14 +16,15 @@
package org.springframework.web.method.support;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter;
import org.springframework.util.Assert;
import org.springframework.web.bind.support.WebDataBinderFactory;
......@@ -41,10 +42,11 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
protected final Log logger = LogFactory.getLog(getClass());
private final List<HandlerMethodArgumentResolver> argumentResolvers =
new ArrayList<HandlerMethodArgumentResolver>();
new LinkedList<HandlerMethodArgumentResolver>();
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>();
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>(256);
/**
* Return a read-only list with the contained resolvers, or an empty list.
......@@ -81,7 +83,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) {
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (logger.isTraceEnabled()) {
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
parameter.getGenericParameterType() + "]");
......
/*
* 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.
......@@ -151,7 +151,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
private BeanExpressionContext expressionContext;
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>();
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>(64);
/**
......
/*
* 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.
......@@ -30,7 +30,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.portlet.ClientDataRequest;
import javax.portlet.Event;
import javax.portlet.EventRequest;
......@@ -76,11 +75,14 @@ import org.springframework.web.servlet.View;
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
// dummy method placeholder
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
private static final Method NO_METHOD_FOUND =
ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>(64);
private WebArgumentResolver[] customArgumentResolvers;
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache = new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>();
/**
* Set a custom ArgumentResolvers to use for special method parameter types.
......@@ -134,18 +136,18 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
final Class<?> handlerType = handler.getClass();
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
Method handlerMethod = null;
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
Method handlerMethod;
Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType);
if (handlers != null) {
handlerMethod = handlers.get(thrownExceptionType);
if (handlerMethod != null) {
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
}
} else {
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
exceptionHandlerCache.put(handlerType, handlers);
}
else {
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
this.exceptionHandlerCache.put(handlerType, handlers);
}
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
......@@ -205,7 +207,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
/**
* Uses the {@link DepthComparator} to find the best matching method
* Uses the {@link ExceptionDepthComparator} to find the best matching method.
* @return the best matching method or {@code null}.
*/
private Method getBestMatchingMethod(
......@@ -217,7 +219,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
Class<? extends Throwable> closestMatch =
ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException);
Method method = resolverMethods.get(closestMatch);
return ((method == null) || (NO_METHOD_FOUND == method)) ? null : method;
return (method == null || NO_METHOD_FOUND == method ? null : method);
}
/**
......
......@@ -27,7 +27,7 @@ import org.springframework.web.context.WebApplicationContext;
/**
* Tiles2 {@link org.apache.tiles.preparer.PreparerFactory} implementation
* Tiles3 {@link org.apache.tiles.preparer.PreparerFactory} implementation
* that expects preparer class names and builds preparer instances for those,
* creating them through the Spring ApplicationContext in order to apply
* Spring container callbacks and configured Spring BeanPostProcessors.
......@@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext;
*/
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
/** Cache of shared ViewPreparer instances: bean name --> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>();
/** Cache of shared ViewPreparer instances: bean name -> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
@Override
......
/*
* 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.
......@@ -54,7 +54,7 @@ public class UrlFilenameViewController extends AbstractUrlViewController {
private String suffix = "";
/** Request URL path String --> view name String */
private final Map<String, String> viewNameCache = new ConcurrentHashMap<String, String>();
private final Map<String, String> viewNameCache = new ConcurrentHashMap<String, String>(256);
/**
......
......@@ -35,7 +35,6 @@ import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
......@@ -46,6 +45,7 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
......@@ -56,7 +56,6 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.Ordered;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
......@@ -188,9 +187,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
private BeanExpressionContext expressionContext;
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache =
new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>();
new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>(64);
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>();
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>(64);
public AnnotationMethodHandlerAdapter() {
......
......@@ -32,7 +32,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
......@@ -82,7 +81,7 @@ import org.springframework.web.servlet.support.RequestContextUtils;
* @author Juergen Hoeller
* @since 3.0
*
* @deprecated in Spring 3.2 in favor of
* @deprecated as of Spring 3.2, in favor of
* {@link org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver}
*/
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
......@@ -91,7 +90,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>();
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>(64);
private WebArgumentResolver[] customArgumentResolvers;
......@@ -162,8 +161,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
Method handlerMethod = null;
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType);
if (handlers != null) {
handlerMethod = handlers.get(thrownExceptionType);
if (handlerMethod != null) {
......@@ -171,8 +169,8 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
}
}
else {
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
exceptionHandlerCache.put(handlerType, handlers);
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
this.exceptionHandlerCache.put(handlerType, handlers);
}
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
......
......@@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source;
......@@ -39,7 +38,6 @@ import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest;
......@@ -82,7 +80,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>();
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64);
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();
......
......@@ -157,14 +157,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache =
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>();
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>(64);
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<Class<?>, Set<Method>>();
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<Class<?>, Set<Method>>(64);
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache =
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<Class<?>, Set<Method>>();
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<Class<?>, Set<Method>>(64);
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache =
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
......
/*
* 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.
......@@ -43,7 +43,7 @@ public class InternalPathMethodNameResolver extends AbstractUrlMethodNameResolve
private String suffix = "";
/** Request URL path String --> method name String */
private final Map<String, String> methodNameCache = new ConcurrentHashMap<String, String>();
private final Map<String, String> methodNameCache = new ConcurrentHashMap<String, String>(16);
/**
......
/*
* 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.
......@@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext;
*/
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
/** Cache of shared ViewPreparer instances: bean name --> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>();
/** Cache of shared ViewPreparer instances: bean name -> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
@Override
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册