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:
Juergen Hoeller 2012-12-12 23:46:26 +01:00
parent a2f8902b3a
commit b9df7d68d9
58 changed files with 380 additions and 387 deletions

View File

@ -46,7 +46,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
*/ */
private int order = Ordered.LOWEST_PRECEDENCE; 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) { public void setBeanClassLoader(ClassLoader beanClassLoader) {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.aopalliance.aop.Advice; import org.aopalliance.aop.Advice;
@ -136,15 +133,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
private BeanFactory beanFactory; 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<?>>(16);
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>();
/** /**
@ -264,19 +261,19 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
Object cacheKey = getCacheKey(bean.getClass(), beanName); Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.add(cacheKey); this.earlyProxyReferences.put(cacheKey, Boolean.TRUE);
return wrapIfNecessary(bean, beanName, cacheKey); return wrapIfNecessary(bean, beanName, cacheKey);
} }
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); Object cacheKey = getCacheKey(beanClass, beanName);
if (!this.targetSourcedBeans.contains(cacheKey)) { if (!this.targetSourcedBeans.containsKey(beanName)) {
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) { if (this.advisedBeans.containsKey(cacheKey)) {
return null; return null;
} }
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.nonAdvisedBeans.add(cacheKey); this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null; return null;
} }
} }
@ -286,7 +283,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
// The TargetSource will handle target instances in a custom fashion. // The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName); TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) { if (targetSource != null) {
this.targetSourcedBeans.add(beanName); this.targetSourcedBeans.put(beanName, Boolean.TRUE);
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass()); 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 { public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) { if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName); Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) { if (!this.earlyProxyReferences.containsKey(cacheKey)) {
return wrapIfNecessary(bean, beanName, 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 * @return a proxy wrapping the bean, or the raw bean instance as-is
*/ */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (this.targetSourcedBeans.contains(beanName)) { if (this.targetSourcedBeans.containsKey(beanName)) {
return bean; return bean;
} }
if (this.nonAdvisedBeans.contains(cacheKey)) { if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean; return bean;
} }
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.nonAdvisedBeans.add(cacheKey); this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean; return bean;
} }
// Create proxy if we have advice. // Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) { 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)); Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass()); this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy; return proxy;
} }
this.nonAdvisedBeans.add(cacheKey); this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean; return bean;
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,7 +16,6 @@
package org.springframework.aop.target; package org.springframework.aop.target;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; 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. * 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; private int invocationCount;
@ -85,7 +84,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
// Associate target with ThreadLocal. // Associate target with ThreadLocal.
target = newPrototypeInstance(); target = newPrototypeInstance();
this.targetInThread.set(target); this.targetInThread.set(target);
this.targetSet.add(target); synchronized (this.targetSet) {
this.targetSet.add(target);
}
} }
else { else {
++this.hitCount; ++this.hitCount;
@ -119,7 +120,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
} }
public int getObjectCount() { public int getObjectCount() {
return this.targetSet.size(); synchronized (this.targetSet) {
return this.targetSet.size();
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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); private static final Log logger = LogFactory.getLog(BeanUtils.class);
// using WeakHashMap as a Set
private static final Map<Class<?>, Boolean> unknownEditorTypes = private static final Map<Class<?>, Boolean> unknownEditorTypes =
Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>()); Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>());

View File

@ -22,7 +22,6 @@ import java.beans.Introspector;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import java.lang.ref.Reference; import java.lang.ref.Reference;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -70,14 +69,14 @@ public class CachedIntrospectionResults {
* Set of ClassLoaders that this CachedIntrospectionResults class will always * Set of ClassLoaders that this CachedIntrospectionResults class will always
* accept classes from, even if the classes do not qualify as cache-safe. * 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. * Map keyed by class containing CachedIntrospectionResults.
* Needs to be a WeakHashMap with WeakReferences as values to allow * Needs to be a WeakHashMap with WeakReferences as values to allow
* for proper garbage collection in case of multiple class loaders. * 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) { public static void acceptClassLoader(ClassLoader classLoader) {
if (classLoader != null) { 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 { static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
CachedIntrospectionResults results; CachedIntrospectionResults results;
Object value = classCache.get(beanClass); Object value;
synchronized (classCache) {
value = classCache.get(beanClass);
}
if (value instanceof Reference) { if (value instanceof Reference) {
Reference ref = (Reference) value; Reference ref = (Reference) value;
results = (CachedIntrospectionResults) ref.get(); results = (CachedIntrospectionResults) ref.get();
@ -149,14 +153,18 @@ public class CachedIntrospectionResults {
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) || if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
isClassLoaderAccepted(beanClass.getClassLoader())) { isClassLoaderAccepted(beanClass.getClassLoader())) {
results = new CachedIntrospectionResults(beanClass); results = new CachedIntrospectionResults(beanClass);
classCache.put(beanClass, results); synchronized (classCache) {
classCache.put(beanClass, results);
}
} }
else { else {
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe"); logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
} }
results = new CachedIntrospectionResults(beanClass); results = new CachedIntrospectionResults(beanClass);
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results)); synchronized (classCache) {
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
}
} }
} }
return results; return results;
@ -172,8 +180,10 @@ public class CachedIntrospectionResults {
private static boolean isClassLoaderAccepted(ClassLoader classLoader) { private static boolean isClassLoaderAccepted(ClassLoader classLoader) {
// Iterate over array copy in order to avoid synchronization for the entire // Iterate over array copy in order to avoid synchronization for the entire
// ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator). // ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator).
ClassLoader[] acceptedLoaderArray = ClassLoader[] acceptedLoaderArray;
acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]); synchronized (acceptedClassLoaders) {
acceptedLoaderArray = acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
}
for (ClassLoader registeredLoader : acceptedLoaderArray) { for (ClassLoader registeredLoader : acceptedLoaderArray) {
if (isUnderneathClassLoader(classLoader, registeredLoader)) { if (isUnderneathClassLoader(classLoader, registeredLoader)) {
return true; return true;

View File

@ -119,10 +119,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
private ConfigurableListableBeanFactory beanFactory; private ConfigurableListableBeanFactory beanFactory;
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache = private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
new ConcurrentHashMap<Class<?>, Constructor<?>[]>(); new ConcurrentHashMap<Class<?>, Constructor<?>[]>(64);
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache = private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<Class<?>, InjectionMetadata>(); new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
/** /**

View File

@ -24,8 +24,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.Map; import java.util.Map;
@ -85,7 +83,7 @@ public class InitDestroyAnnotationBeanPostProcessor
private int order = Ordered.LOWEST_PRECEDENCE; private int order = Ordered.LOWEST_PRECEDENCE;
private transient final Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache = 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 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, public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods,
Collection<LifecycleElement> destroyMethods) { Collection<LifecycleElement> destroyMethods) {
if (!initMethods.isEmpty()) { this.targetClass = targetClass;
this.initMethods = Collections.synchronizedSet(new LinkedHashSet<LifecycleElement>(initMethods.size())); this.initMethods = initMethods;
for (LifecycleElement element : initMethods) { this.destroyMethods = destroyMethods;
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();
}
} }
public void checkConfigMembers(RootBeanDefinition beanDefinition) { public void checkConfigMembers(RootBeanDefinition beanDefinition) {
synchronized(this.initMethods) { Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<LifecycleElement>(this.initMethods.size());
for (Iterator<LifecycleElement> it = this.initMethods.iterator(); it.hasNext();) { for (LifecycleElement element : this.initMethods) {
String methodIdentifier = it.next().getIdentifier(); String methodIdentifier = element.getIdentifier();
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) { if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier); beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
} checkedInitMethods.add(element);
else { if (logger.isDebugEnabled()) {
it.remove(); logger.debug("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
} }
} }
} }
synchronized(this.destroyMethods) { Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<LifecycleElement>(this.destroyMethods.size());
for (Iterator<LifecycleElement> it = this.destroyMethods.iterator(); it.hasNext();) { for (LifecycleElement element : this.destroyMethods) {
String methodIdentifier = it.next().getIdentifier(); String methodIdentifier = element.getIdentifier();
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) { if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier); beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
} checkedDestroyMethods.add(element);
else { if (logger.isDebugEnabled()) {
it.remove(); 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 { 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(); boolean debug = logger.isDebugEnabled();
for (LifecycleElement element : this.initMethods) { for (LifecycleElement element : initMethodsToIterate) {
if (debug) { if (debug) {
logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod()); 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 { 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(); boolean debug = logger.isDebugEnabled();
for (LifecycleElement element : this.destroyMethods) { for (LifecycleElement element : destroyMethodsToIterate) {
if (debug) { if (debug) {
logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod()); logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
} }

View File

@ -22,8 +22,6 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Set; import java.util.Set;
@ -50,42 +48,39 @@ public class InjectionMetadata {
private final Log logger = LogFactory.getLog(InjectionMetadata.class); 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) { public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
if (!elements.isEmpty()) { this.targetClass = targetClass;
this.injectedElements = Collections.synchronizedSet(new LinkedHashSet<InjectedElement>(elements.size())); this.injectedElements = elements;
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();
}
} }
public void checkConfigMembers(RootBeanDefinition beanDefinition) { public void checkConfigMembers(RootBeanDefinition beanDefinition) {
synchronized (this.injectedElements) { Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
for (Iterator<InjectedElement> it = this.injectedElements.iterator(); it.hasNext();) { for (InjectedElement element : this.injectedElements) {
Member member = it.next().getMember(); Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) { if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member); beanDefinition.registerExternallyManagedConfigMember(member);
} checkedElements.add(element);
else { if (logger.isDebugEnabled()) {
it.remove(); 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 { 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(); boolean debug = logger.isDebugEnabled();
for (InjectedElement element : this.injectedElements) { for (InjectedElement element : elementsToIterate) {
if (debug) { if (debug) {
logger.debug("Processing injected method of bean '" + beanName + "': " + element); logger.debug("Processing injected method of bean '" + beanName + "': " + element);
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.annotation.Annotation;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List; 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.BeansException;
import org.springframework.beans.PropertyValues; import org.springframework.beans.PropertyValues;
@ -89,8 +88,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
private ConfigurableListableBeanFactory beanFactory; 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) PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
throws BeansException { throws BeansException {
if (!this.validatedBeanNames.contains(beanName)) { if (!this.validatedBeanNames.containsKey(beanName)) {
if (!shouldSkip(this.beanFactory, beanName)) { if (!shouldSkip(this.beanFactory, beanName)) {
List<String> invalidProperties = new ArrayList<String>(); List<String> invalidProperties = new ArrayList<String>();
for (PropertyDescriptor pd : pds) { for (PropertyDescriptor pd : pds) {
@ -149,7 +151,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName)); throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
} }
} }
this.validatedBeanNames.add(beanName); this.validatedBeanNames.put(beanName, Boolean.TRUE);
} }
return pvs; return pvs;
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,11 +16,10 @@
package org.springframework.beans.factory.config; package org.springframework.beans.factory.config;
import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.concurrent.ConcurrentHashMap;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue; import org.springframework.beans.PropertyValue;
@ -71,8 +70,11 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
private boolean ignoreInvalidKeys = false; 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 beanName = key.substring(0, separatorIndex);
String beanProperty = key.substring(separatorIndex+1); String beanProperty = key.substring(separatorIndex+1);
this.beanNames.add(beanName); this.beanNames.put(beanName, Boolean.TRUE);
applyPropertyValue(factory, beanName, beanProperty, value); applyPropertyValue(factory, beanName, beanProperty, value);
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Property '" + key + "' set to value [" + value + "]"); logger.debug("Property '" + key + "' set to value [" + value + "]");
@ -159,7 +161,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
* the named bean * the named bean
*/ */
public boolean hasPropertyOverridesFor(String beanName) { public boolean hasPropertyOverridesFor(String beanName) {
return this.beanNames.contains(beanName); return this.beanNames.containsKey(beanName);
} }
} }

View File

@ -145,11 +145,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */ /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
private final Map<String, BeanWrapper> factoryBeanInstanceCache = private final Map<String, BeanWrapper> factoryBeanInstanceCache =
new ConcurrentHashMap<String, BeanWrapper>(); new ConcurrentHashMap<String, BeanWrapper>(16);
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */ /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache = private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
new ConcurrentHashMap<Class, PropertyDescriptor[]>(); new ConcurrentHashMap<Class, PropertyDescriptor[]>(64);
/** /**

View File

@ -24,7 +24,6 @@ import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction; import java.security.PrivilegedExceptionAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
@ -151,17 +150,20 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
private boolean hasDestructionAwareBeanPostProcessors; private boolean hasDestructionAwareBeanPostProcessors;
/** Map from scope identifier String to corresponding Scope */ /** 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 */ /** Security context used when running with a SecurityManager */
private SecurityContextProvider securityContextProvider; private SecurityContextProvider securityContextProvider;
/** Map from bean name to merged RootBeanDefinition */ /** Map from bean name to merged RootBeanDefinition */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = 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 */ /** Names of beans that are currently in creation */
private final ThreadLocal<Object> prototypesCurrentlyInCreation = private final ThreadLocal<Object> prototypesCurrentlyInCreation =
@ -1372,7 +1374,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
* @param beanName the name of the bean * @param beanName the name of the bean
*/ */
protected void markBeanAsCreated(String beanName) { 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 * at this point already
*/ */
protected boolean isBeanEligibleForMetadataCaching(String beanName) { 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 * @return <code>true</code> if actually removed, <code>false</code> otherwise
*/ */
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) { protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
if (!this.alreadyCreated.contains(beanName)) { if (!this.alreadyCreated.containsKey(beanName)) {
removeSingleton(beanName); removeSingleton(beanName);
return true; return true;
} }

View File

@ -112,7 +112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
/** Map from serialized id to factory instance */ /** Map from serialized id to factory instance */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories = 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 */ /** Optional id for this factory, for serialization purposes */
private String serializationId; private String serializationId;
@ -127,16 +127,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** Map from dependency type to corresponding autowired value */ /** 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 */ /** 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 */ /** 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 */ /** 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 */ /** List of bean definition names, in registration order */
private final List<String> beanDefinitionNames = new ArrayList<String>(); private final List<String> beanDefinitionNames = new ArrayList<String>();

View File

@ -81,22 +81,22 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
/** Cache of singleton objects: bean name --> bean instance */ /** 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 */ /** 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 */ /** 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 */ /** 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) */ /** 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) */ /** 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 */ /** List of suppressed Exceptions, available for associating related causes */
private Set<Exception> suppressedExceptions; private Set<Exception> suppressedExceptions;
@ -108,13 +108,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>(); 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 */ /** 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 */ /** 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 */ /** 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 { public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */ /** 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);
/** /**

View File

@ -18,9 +18,8 @@ package org.springframework.beans.factory.support;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Collections; import java.util.Map;
import java.util.HashSet; import java.util.concurrent.ConcurrentHashMap;
import java.util.Set;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
@ -48,11 +47,14 @@ import org.springframework.util.Assert;
*/ */
public class RootBeanDefinition extends AbstractBeanDefinition { 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; private BeanDefinitionHolder decoratedDefinition;
@ -277,27 +279,27 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
public void registerExternallyManagedConfigMember(Member configMember) { public void registerExternallyManagedConfigMember(Member configMember) {
this.externallyManagedConfigMembers.add(configMember); this.externallyManagedConfigMembers.put(configMember, Boolean.TRUE);
} }
public boolean isExternallyManagedConfigMember(Member configMember) { public boolean isExternallyManagedConfigMember(Member configMember) {
return this.externallyManagedConfigMembers.contains(configMember); return this.externallyManagedConfigMembers.containsKey(configMember);
} }
public void registerExternallyManagedInitMethod(String initMethod) { public void registerExternallyManagedInitMethod(String initMethod) {
this.externallyManagedInitMethods.add(initMethod); this.externallyManagedInitMethods.put(initMethod, Boolean.TRUE);
} }
public boolean isExternallyManagedInitMethod(String initMethod) { public boolean isExternallyManagedInitMethod(String initMethod) {
return this.externallyManagedInitMethods.contains(initMethod); return this.externallyManagedInitMethods.containsKey(initMethod);
} }
public void registerExternallyManagedDestroyMethod(String destroyMethod) { public void registerExternallyManagedDestroyMethod(String destroyMethod) {
this.externallyManagedDestroyMethods.add(destroyMethod); this.externallyManagedDestroyMethods.put(destroyMethod, Boolean.TRUE);
} }
public boolean isExternallyManagedDestroyMethod(String destroyMethod) { public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
return this.externallyManagedDestroyMethods.contains(destroyMethod); return this.externallyManagedDestroyMethods.containsKey(destroyMethod);
} }
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) { public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
/** Map of bean definition objects, keyed by bean name */ /** 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) public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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()) { if (logger.isDebugEnabled()) {
logger.debug("Loaded NamespaceHandler mappings: " + mappings); 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); CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings; this.handlerMappings = handlerMappings;
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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()) { if (logger.isDebugEnabled()) {
logger.debug("Loaded schema mappings: " + mappings); 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); CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
this.schemaMappings = schemaMappings; this.schemaMappings = schemaMappings;
} }

View File

@ -56,7 +56,7 @@ public class ConcurrentMapCache implements Cache {
* @param name the name of the cache * @param name the name of the cache
*/ */
public ConcurrentMapCache(String name) { 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 * @param allowNullValues whether to accept and convert null values for this cache
*/ */
public ConcurrentMapCache(String name, boolean allowNullValues) { public ConcurrentMapCache(String name, boolean allowNullValues) {
this(name, new ConcurrentHashMap<Object, Object>(), allowNullValues); this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues);
} }
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { 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; private boolean dynamic = true;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.BridgeMethodResolver; import org.springframework.core.BridgeMethodResolver;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -48,6 +49,7 @@ import org.springframework.util.ObjectUtils;
* configurable. * configurable.
* *
* @author Costin Leau * @author Costin Leau
* @author Juergen Hoeller
* @since 3.1 * @since 3.1
*/ */
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource { 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 * <p>As this base class is not marked Serializable, the cache will be recreated
* after serialization - provided that the concrete subclass is Serializable. * 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);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { class ExpressionEvaluator {
private SpelExpressionParser parser = new SpelExpressionParser(); private final SpelExpressionParser parser = new SpelExpressionParser();
// shared param discoverer since it caches data internally // 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( public EvaluationContext createEvaluationContext(

View File

@ -29,9 +29,8 @@ import org.springframework.cache.CacheManager;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
* Abstract base class implementing the common {@link CacheManager} * Abstract base class implementing the common {@link CacheManager} methods.
* methods. Useful for 'static' environments where the backing caches do * Useful for 'static' environments where the backing caches do not change.
* not change.
* *
* @author Costin Leau * @author Costin Leau
* @author Juergen Hoeller * @author Juergen Hoeller
@ -39,9 +38,9 @@ import org.springframework.util.Assert;
*/ */
public abstract class AbstractCacheManager implements CacheManager, InitializingBean { 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() { public void afterPropertiesSet() {

View File

@ -1,5 +1,5 @@
/* /*
* 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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public class NoOpCacheManager implements CacheManager {
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(); private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(16);
private Set<String> names = new LinkedHashSet<String>();
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 { private static class NoOpCache implements Cache {
@ -61,7 +89,7 @@ public class NoOpCacheManager implements CacheManager {
} }
public String getName() { public String getName() {
return name; return this.name;
} }
public Object getNativeCache() { 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);
}
} }

View File

@ -178,7 +178,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
private transient BeanFactory beanFactory; private transient BeanFactory beanFactory;
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache = 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; protected boolean shareable = true;
private volatile boolean cached = false;
private volatile Object cachedFieldValue;
public ResourceElement(Member member, PropertyDescriptor pd) { public ResourceElement(Member member, PropertyDescriptor pd) {
super(member, pd); super(member, pd);
} }

View File

@ -53,7 +53,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false); private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache = private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(); new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
private BeanFactory beanFactory; private BeanFactory beanFactory;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 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 = private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(); new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(8);
private final ParserContext beanExpressionParserContext = new ParserContext() { private final ParserContext beanExpressionParserContext = new ParserContext() {
public boolean isTemplate() { public boolean isTemplate() {

View File

@ -1387,7 +1387,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
*/ */
private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor { 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) { public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanDefinition.isSingleton()) { if (beanDefinition.isSingleton()) {

View File

@ -53,10 +53,10 @@ public class FormattingConversionService extends GenericConversionService
private StringValueResolver embeddedValueResolver; private StringValueResolver embeddedValueResolver;
private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters = private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters =
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(); new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
private final Map<AnnotationConverterKey, GenericConverter> cachedParsers = private final Map<AnnotationConverterKey, GenericConverter> cachedParsers =
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(); new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
public void setEmbeddedValueResolver(StringValueResolver resolver) { public void setEmbeddedValueResolver(StringValueResolver resolver) {
@ -214,11 +214,14 @@ public class FormattingConversionService extends GenericConversionService
return sourceType.hasAnnotation(annotationType); return sourceType.hasAnnotation(annotationType);
} }
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 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); GenericConverter converter = cachedPrinters.get(converterKey);
if (converter == null) { 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); converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this);
cachedPrinters.put(converterKey, converter); cachedPrinters.put(converterKey, converter);
} }
@ -226,7 +229,8 @@ public class FormattingConversionService extends GenericConversionService
} }
public String toString() { 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); return targetType.hasAnnotation(annotationType);
} }
@SuppressWarnings("unchecked")
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { 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); GenericConverter converter = cachedParsers.get(converterKey);
if (converter == null) { 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); converter = new ParserConverter(fieldType, parser, FormattingConversionService.this);
cachedParsers.put(converterKey, converter); cachedParsers.put(converterKey, converter);
} }
@ -266,7 +273,8 @@ public class FormattingConversionService extends GenericConversionService
} }
public String toString() { public String toString() {
return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName() + ": " + annotationFormatterFactory; return String.class.getName() + " -> @" + annotationType.getName() + " " +
fieldType.getName() + ": " + annotationFormatterFactory;
} }
} }

View File

@ -42,10 +42,9 @@ import org.springframework.util.ClassUtils;
* information in the method attributes to discover parameter names. Returns * information in the method attributes to discover parameter names. Returns
* <code>null</code> if the class file was compiled without debug information. * <code>null</code> if the class file was compiled without debug information.
* *
* <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer * <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer instance
* instance caches the ASM discovered information for each introspected Class, in a * caches the ASM discovered information for each introspected Class, in a thread-safe
* thread-safe manner. It is recommended to reuse discoverer instances * manner. It is recommended to reuse ParameterNameDiscoverer instances as far as possible.
* as far as possible.
* *
* @author Adrian Colyer * @author Adrian Colyer
* @author Costin Leau * @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 // 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 = 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) { public String[] getParameterNames(Method method) {
@ -111,7 +110,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
} }
try { try {
ClassReader classReader = new ClassReader(is); 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); classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);
return map; return map;
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public class SimpleAliasRegistry implements AliasRegistry {
/** Map from alias to canonical name */ /** 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) { public void registerAlias(String name, String alias) {

View File

@ -74,7 +74,7 @@ public class GenericConversionService implements ConfigurableConversionService {
private final Converters converters = new Converters(); private final Converters converters = new Converters();
private final Map<ConverterCacheKey, GenericConverter> converterCache = private final Map<ConverterCacheKey, GenericConverter> converterCache =
new ConcurrentHashMap<ConverterCacheKey, GenericConverter>(); new ConcurrentHashMap<ConverterCacheKey, GenericConverter>(64);
// implementing ConverterRegistry // implementing ConverterRegistry
@ -182,8 +182,8 @@ public class GenericConversionService implements ConfigurableConversionService {
* @param targetType the target type * @param targetType the target type
* @return the converted value * @return the converted value
* @throws ConversionException if a conversion exception occurred * @throws ConversionException if a conversion exception occurred
* @throws IllegalArgumentException if targetType is null * @throws IllegalArgumentException if targetType is null,
* @throws IllegalArgumentException if sourceType is null but source is not null * or sourceType is null but source is not null
*/ */
public Object convert(Object source, TypeDescriptor targetType) { public Object convert(Object source, TypeDescriptor targetType) {
return convert(source, TypeDescriptor.forObject(source), targetType); return convert(source, TypeDescriptor.forObject(source), targetType);
@ -480,7 +480,6 @@ public class GenericConversionService implements ConfigurableConversionService {
* @param sourceType the source type * @param sourceType the source type
* @param targetType the target type * @param targetType the target type
* @return a {@link GenericConverter} or <tt>null</tt> * @return a {@link GenericConverter} or <tt>null</tt>
* @see #getTypeHierarchy(Class)
*/ */
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) { public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
// Search the full type hierarchy // Search the full type hierarchy

View File

@ -46,11 +46,11 @@ import org.springframework.util.StringUtils;
*/ */
public class ReflectivePropertyAccessor implements PropertyAccessor { 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); Field field = findField(name, type, target);
if (field != null) { if (field != null) {
TypeDescriptor typeDescriptor = new TypeDescriptor(field); 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); this.typeDescriptorCache.put(cacheKey, typeDescriptor);
return true; return true;
} }
@ -264,15 +264,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
return TypeDescriptor.valueOf(Integer.TYPE); return TypeDescriptor.valueOf(Integer.TYPE);
} }
CacheKey cacheKey = new CacheKey(type, name); CacheKey cacheKey = new CacheKey(type, name);
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
if (typeDescriptor == null) { if (typeDescriptor == null) {
// attempt to populate the cache entry // attempt to populate the cache entry
try { try {
if (canRead(context, target, name)) { if (canRead(context, target, name)) {
typeDescriptor = this.typeDescriptorCache.get(cacheKey); typeDescriptor = this.typeDescriptorCache.get(cacheKey);
} }
else if (canWrite(context, target, name)) { else if (canWrite(context, target, name)) {
typeDescriptor = this.typeDescriptorCache.get(cacheKey); typeDescriptor = this.typeDescriptorCache.get(cacheKey);
} }
} }
catch (AccessException ex) { catch (AccessException ex) {

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 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);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,9 +16,8 @@
package org.springframework.orm.hibernate3; package org.springframework.orm.hibernate3;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.FlushMode; import org.hibernate.FlushMode;
import org.hibernate.Session; import org.hibernate.Session;
@ -44,10 +43,10 @@ public class SessionHolder extends ResourceHolderSupport {
private static final Object DEFAULT_KEY = new Object(); 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. * 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; private Transaction transaction;
@ -89,12 +88,10 @@ public class SessionHolder extends ResourceHolderSupport {
} }
public Session getAnySession() { public Session getAnySession() {
synchronized (this.sessionMap) { if (!this.sessionMap.isEmpty()) {
if (!this.sessionMap.isEmpty()) { return this.sessionMap.values().iterator().next();
return this.sessionMap.values().iterator().next();
}
return null;
} }
return null;
} }
public void addSession(Session session) { public void addSession(Session session) {
@ -120,10 +117,8 @@ public class SessionHolder extends ResourceHolderSupport {
} }
public boolean doesNotHoldNonDefaultSession() { public boolean doesNotHoldNonDefaultSession() {
synchronized (this.sessionMap) { return this.sessionMap.isEmpty() ||
return this.sessionMap.isEmpty() || (this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
(this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
}
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 ListableBeanFactory beanFactory;
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache = private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
new ConcurrentHashMap<Class<?>, InjectionMetadata>(); new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
private final Map<Object, EntityManager> extendedEntityManagersToClose = private final Map<Object, EntityManager> extendedEntityManagersToClose =
new ConcurrentHashMap<Object, EntityManager>(); new ConcurrentHashMap<Object, EntityManager>(16);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.naming.NamingException; import javax.naming.NamingException;
import org.springframework.jndi.JndiTemplate; import org.springframework.jndi.JndiTemplate;
/** /**
* Simple extension of the JndiTemplate class that always returns a given * Simple extension of the JndiTemplate class that always returns a given object.
* object. Very useful for testing. Effectively a mock object. *
* * <p>Very useful for testing. Effectively a mock object.
*
* @author Rod Johnson * @author Rod Johnson
* @author Juergen Hoeller * @author Juergen Hoeller
*/ */
public class ExpectedLookupTemplate extends JndiTemplate { 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 * Construct a new JndiTemplate that will always return given objects for
* given names. To be populated through <code>addObject</code> calls. * given names. To be populated through <code>addObject</code> calls.
*
* @see #addObject(String, Object) * @see #addObject(String, Object)
*/ */
public ExpectedLookupTemplate() { public ExpectedLookupTemplate() {
@ -47,7 +46,6 @@ public class ExpectedLookupTemplate extends JndiTemplate {
/** /**
* Construct a new JndiTemplate that will always return the given object, * Construct a new JndiTemplate that will always return the given object,
* but honour only requests for the given name. * but honour only requests for the given name.
*
* @param name the name the client is expected to look up * @param name the name the client is expected to look up
* @param object the object that will be returned * @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 * Add the given object to the list of JNDI objects that this template will expose.
* expose.
*
* @param name the name the client is expected to look up * @param name the name the client is expected to look up
* @param object the object that will be returned * @param object the object that will be returned
*/ */

View File

@ -44,7 +44,8 @@ class ContextCache {
/** /**
* Map of context keys to Spring ApplicationContext instances. * 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; private int hitCount;
@ -69,7 +70,6 @@ class ContextCache {
/** /**
* Return whether there is a cached context for the given key. * Return whether there is a cached context for the given key.
*
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
*/ */
boolean contains(MergedContextConfiguration key) { boolean contains(MergedContextConfiguration key) {
@ -79,10 +79,8 @@ class ContextCache {
/** /**
* Obtain a cached ApplicationContext for the given key. * Obtain a cached ApplicationContext for the given key.
*
* <p>The {@link #getHitCount() hit} and {@link #getMissCount() miss} * <p>The {@link #getHitCount() hit} and {@link #getMissCount() miss}
* counts will be updated accordingly. * counts will be updated accordingly.
*
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @return the corresponding ApplicationContext instance, * @return the corresponding ApplicationContext instance,
* or <code>null</code> if not found in the cache. * 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. * Explicitly add an ApplicationContext instance to the cache under the given key.
*
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @param context the ApplicationContext instance (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. * Remove the context with the given key.
*
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @return the corresponding ApplicationContext instance, or <code>null</code> * @return the corresponding ApplicationContext instance, or <code>null</code>
* if not found in the cache. * if not found in the cache.
@ -162,11 +158,9 @@ class ContextCache {
* {@link #remove removing} the context from the cache and explicitly * {@link #remove removing} the context from the cache and explicitly
* {@link ConfigurableApplicationContext#close() closing} it if it is an * {@link ConfigurableApplicationContext#close() closing} it if it is an
* instance of {@link ConfigurableApplicationContext}. * instance of {@link ConfigurableApplicationContext}.
*
* <p>Generally speaking, you would only call this method if you change the * <p>Generally speaking, you would only call this method if you change the
* state of a singleton bean, potentially affecting future interaction with * state of a singleton bean, potentially affecting future interaction with
* the context. * the context.
*
* @param key the context key (never <code>null</code>) * @param key the context key (never <code>null</code>)
* @see #remove * @see #remove
*/ */
@ -192,11 +186,8 @@ class ContextCache {
* as the {@link #hitCount hit} and {@link #missCount miss} counts. * as the {@link #hitCount hit} and {@link #missCount miss} counts.
*/ */
public String toString() { public String toString() {
return new ToStringCreator(this)// return new ToStringCreator(this).append("size", size()).append("hitCount", getHitCount()).
.append("size", size())// append("missCount", getMissCount()).toString();
.append("hitCount", getHitCount())//
.append("missCount", getMissCount())//
.toString();
} }
} }

View File

@ -21,12 +21,13 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanFactoryUtils;
@ -111,7 +112,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource(); protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource();
private final Map<Method, TransactionContext> transactionContextCache = private final Map<Method, TransactionContext> transactionContextCache =
Collections.synchronizedMap(new IdentityHashMap<Method, TransactionContext>()); new ConcurrentHashMap<Method, TransactionContext>(8);
private TransactionConfigurationAttributes configurationAttributes; private TransactionConfigurationAttributes configurationAttributes;

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 * <p>As this base class is not marked Serializable, the cache will be recreated
* after serialization - provided that the concrete subclass is Serializable. * 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);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; import org.springframework.util.Assert;
/** /**
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} that * Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters}
* use JAXB2. Creates {@link JAXBContext} object lazily. * that use JAXB2. Creates {@link JAXBContext} object lazily.
* *
* @author Arjen Poutsma * @author Arjen Poutsma
* @since 3.0 * @since 3.0
*/ */
public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHttpMessageConverter<T> { 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 * @param clazz the class to create the marshaller for
* @return the {@code Marshaller} * @return the {@code Marshaller}
* @throws HttpMessageConversionException in case of JAXB errors * @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 * @param clazz the class to create the unmarshaller for
* @return the {@code Unmarshaller} * @return the {@code Unmarshaller}
* @throws HttpMessageConversionException in case of JAXB errors * @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 * @param clazz the class to return the context for
* @return the {@code JAXBContext} * @return the {@code JAXBContext}
* @throws HttpMessageConversionException in case of JAXB errors * @throws HttpMessageConversionException in case of JAXB errors
*/ */
protected final JAXBContext getJaxbContext(Class clazz) { protected final JAXBContext getJaxbContext(Class clazz) {
Assert.notNull(clazz, "'clazz' must not be null"); Assert.notNull(clazz, "'clazz' must not be null");
JAXBContext jaxbContext = jaxbContexts.get(clazz); JAXBContext jaxbContext = this.jaxbContexts.get(clazz);
if (jaxbContext == null) { if (jaxbContext == null) {
try { try {
jaxbContext = JAXBContext.newInstance(clazz); jaxbContext = JAXBContext.newInstance(clazz);
jaxbContexts.putIfAbsent(clazz, jaxbContext); this.jaxbContexts.putIfAbsent(clazz, jaxbContext);
} }
catch (JAXBException ex) { catch (JAXBException ex) {
throw new HttpMessageConversionException( throw new HttpMessageConversionException(

View File

@ -13,10 +13,11 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package org.springframework.web.accept; package org.springframework.web.accept;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
@ -37,11 +38,12 @@ import org.springframework.util.MultiValueMap;
*/ */
public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver { 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 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. * Create an instance with the given mappings between extensions and media types.
@ -89,4 +91,4 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten
} }
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.BridgeMethodResolver; import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
@ -64,7 +65,8 @@ public class HandlerMethodResolver {
private final Set<Class> sessionAttributeTypes = new HashSet<Class>(); 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) { public boolean isSessionAttribute(String attrName, Class attrType) {
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) { if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
this.actualSessionAttributeNames.add(attrName); this.actualSessionAttributeNames.put(attrName, Boolean.TRUE);
return true; return true;
} }
else { else {
@ -161,7 +163,7 @@ public class HandlerMethodResolver {
} }
public Set<String> getActualSessionAttributeNames() { public Set<String> getActualSessionAttributeNames() {
return this.actualSessionAttributeNames; return this.actualSessionAttributeNames.keySet();
} }
} }

View File

@ -62,7 +62,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
private final BeanExpressionContext expressionContext; private final BeanExpressionContext expressionContext;
private Map<MethodParameter, NamedValueInfo> namedValueInfoCache = private Map<MethodParameter, NamedValueInfo> namedValueInfoCache =
new ConcurrentHashMap<MethodParameter, NamedValueInfo>(); new ConcurrentHashMap<MethodParameter, NamedValueInfo>(256);
/** /**
* @param beanFactory a bean factory to use for resolving ${...} placeholder * @param beanFactory a bean factory to use for resolving ${...} placeholder
@ -80,11 +80,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
throws Exception { throws Exception {
Class<?> paramType = parameter.getParameterType(); Class<?> paramType = parameter.getParameterType();
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter); NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
Object arg = resolveName(namedValueInfo.name, parameter, webRequest); Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
if (arg == null) { if (arg == null) {
if (namedValueInfo.defaultValue != null) { if (namedValueInfo.defaultValue != null) {
arg = resolveDefaultValue(namedValueInfo.defaultValue); 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 * Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically
* retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}. * retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}.
*
* @param parameter the method parameter * @param parameter the method parameter
* @return the named value information * @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 name the name of the value being resolved
* @param parameter the method parameter to resolve to an argument value * @param parameter the method parameter to resolve to an argument value
* @param request the current request * @param request the current request
*
* @return the resolved argument. May be {@code null} * @return the resolved argument. May be {@code null}
* @throws Exception in case of errors * @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, protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) { ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
} }
/** /**
* Represents the information about a named value, including name, whether it's required and a default value. * 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; this.defaultValue = defaultValue;
} }
} }
} }

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
private final Map<Class<? extends Throwable>, Method> mappedMethods = 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 = 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. * A constructor that finds {@link ExceptionHandler} methods in the given type.

View File

@ -17,11 +17,11 @@
package org.springframework.web.method.annotation; package org.springframework.web.method.annotation;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -50,10 +50,12 @@ public class SessionAttributesHandler {
private final Set<Class<?>> attributeTypes = new HashSet<Class<?>>(); 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; private final SessionAttributeStore sessionAttributeStore;
/** /**
* Create a new instance for a controller type. Session attribute names and * Create a new instance for a controller type. Session attribute names and
* types are extracted from the {@code @SessionAttributes} annotation, if * 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.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) { public boolean isHandlerSessionAttribute(String attributeName, Class<?> attributeType) {
Assert.notNull(attributeName, "Attribute name must not be null"); Assert.notNull(attributeName, "Attribute name must not be null");
if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) { if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) {
this.knownAttributeNames.add(attributeName); this.knownAttributeNames.put(attributeName, Boolean.TRUE);
return true; return true;
} }
else { else {
@ -130,7 +134,7 @@ public class SessionAttributesHandler {
*/ */
public Map<String, Object> retrieveAttributes(WebRequest request) { public Map<String, Object> retrieveAttributes(WebRequest request) {
Map<String, Object> attributes = new HashMap<String, Object>(); 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); Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
if (value != null) { if (value != null) {
attributes.put(name, value); attributes.put(name, value);
@ -146,7 +150,7 @@ public class SessionAttributesHandler {
* @param request the current request * @param request the current request
*/ */
public void cleanupAttributes(WebRequest request) { public void cleanupAttributes(WebRequest request) {
for (String attributeName : this.knownAttributeNames) { for (String attributeName : this.knownAttributeNames.keySet()) {
this.sessionAttributeStore.cleanupAttribute(request, attributeName); this.sessionAttributeStore.cleanupAttribute(request, attributeName);
} }
} }
@ -161,4 +165,4 @@ public class SessionAttributesHandler {
return this.sessionAttributeStore.retrieveAttribute(request, attributeName); return this.sessionAttributeStore.retrieveAttribute(request, attributeName);
} }
} }

View File

@ -16,14 +16,15 @@
package org.springframework.web.method.support; package org.springframework.web.method.support;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.bind.support.WebDataBinderFactory;
@ -41,10 +42,11 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
protected final Log logger = LogFactory.getLog(getClass()); protected final Log logger = LogFactory.getLog(getClass());
private final List<HandlerMethodArgumentResolver> argumentResolvers = private final List<HandlerMethodArgumentResolver> argumentResolvers =
new ArrayList<HandlerMethodArgumentResolver>(); new LinkedList<HandlerMethodArgumentResolver>();
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache = 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. * 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) { private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
if (result == null) { if (result == null) {
for (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) { for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
if (logger.isTraceEnabled()) { if (logger.isTraceEnabled()) {
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
parameter.getGenericParameterType() + "]"); parameter.getGenericParameterType() + "]");

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 BeanExpressionContext expressionContext;
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache = private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>(); new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>(64);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.portlet.ClientDataRequest; import javax.portlet.ClientDataRequest;
import javax.portlet.Event; import javax.portlet.Event;
import javax.portlet.EventRequest; import javax.portlet.EventRequest;
@ -76,11 +75,14 @@ import org.springframework.web.servlet.View;
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver { public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
// dummy method placeholder // 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 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. * 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) { private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
final Class<?> handlerType = handler.getClass(); final Class<?> handlerType = handler.getClass();
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass(); final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
Method handlerMethod = null; Method handlerMethod;
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType);
if (handlers != null) { if (handlers != null) {
handlerMethod = handlers.get(thrownExceptionType); handlerMethod = handlers.get(thrownExceptionType);
if (handlerMethod != null) { if (handlerMethod != null) {
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod); return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
} }
} else { }
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(); else {
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>(); 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}. * @return the best matching method or {@code null}.
*/ */
private Method getBestMatchingMethod( private Method getBestMatchingMethod(
@ -217,7 +219,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
Class<? extends Throwable> closestMatch = Class<? extends Throwable> closestMatch =
ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException); ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException);
Method method = resolverMethods.get(closestMatch); Method method = resolverMethods.get(closestMatch);
return ((method == null) || (NO_METHOD_FOUND == method)) ? null : method; return (method == null || NO_METHOD_FOUND == method ? null : method);
} }
/** /**

View File

@ -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, * that expects preparer class names and builds preparer instances for those,
* creating them through the Spring ApplicationContext in order to apply * creating them through the Spring ApplicationContext in order to apply
* Spring container callbacks and configured Spring BeanPostProcessors. * Spring container callbacks and configured Spring BeanPostProcessors.
@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext;
*/ */
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory { public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
/** Cache of shared ViewPreparer instances: bean name --> bean instance */ /** Cache of shared ViewPreparer instances: bean name -> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(); private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
@Override @Override

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 = ""; private String suffix = "";
/** Request URL path String --> view name String */ /** 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);
/** /**

View File

@ -35,7 +35,6 @@ import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
@ -46,6 +45,7 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryAware;
@ -56,7 +56,6 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.http.HttpEntity; import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage; import org.springframework.http.HttpInputMessage;
@ -188,9 +187,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
private BeanExpressionContext expressionContext; private BeanExpressionContext expressionContext;
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache = 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() { public AnnotationMethodHandlerAdapter() {

View File

@ -32,7 +32,6 @@ import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
@ -82,7 +81,7 @@ import org.springframework.web.servlet.support.RequestContextUtils;
* @author Juergen Hoeller * @author Juergen Hoeller
* @since 3.0 * @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} * {@link org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver}
*/ */
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver { 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 static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache = 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; private WebArgumentResolver[] customArgumentResolvers;
@ -162,8 +161,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass(); final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
Method handlerMethod = null; 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) { if (handlers != null) {
handlerMethod = handlers.get(thrownExceptionType); handlerMethod = handlers.get(thrownExceptionType);
if (handlerMethod != null) { if (handlerMethod != null) {
@ -171,8 +169,8 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
} }
} }
else { else {
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(); handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
exceptionHandlerCache.put(handlerType, handlers); this.exceptionHandlerCache.put(handlerType, handlers);
} }
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>(); final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();

View File

@ -24,7 +24,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.xml.transform.Source; 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.StringHttpMessageConverter;
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
import org.springframework.http.converter.xml.SourceHttpMessageConverter; import org.springframework.http.converter.xml.SourceHttpMessageConverter;
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
@ -82,7 +80,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache = private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(); new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64);
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache = private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>(); new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();

View File

@ -157,14 +157,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = 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 = private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache =
new LinkedHashMap<ControllerAdviceBean, Set<Method>>(); 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 = private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache =
new LinkedHashMap<ControllerAdviceBean, Set<Method>>(); new LinkedHashMap<ControllerAdviceBean, Set<Method>>();

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 = ""; private String suffix = "";
/** Request URL path String --> method name String */ /** 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);
/** /**

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 { public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
/** Cache of shared ViewPreparer instances: bean name --> bean instance */ /** Cache of shared ViewPreparer instances: bean name -> bean instance */
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(); private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
@Override @Override