diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java index e671def56a8..cf22fdddedb 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/AbstractAdvisingBeanPostProcessor.java @@ -46,7 +46,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig */ private int order = Ordered.LOWEST_PRECEDENCE; - private final Map eligibleBeans = new ConcurrentHashMap(); + private final Map eligibleBeans = new ConcurrentHashMap(64); public void setBeanClassLoader(ClassLoader beanClassLoader) { diff --git a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java index 7959b53b026..3216c3e101f 100644 --- a/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java +++ b/spring-aop/src/main/java/org/springframework/aop/framework/autoproxy/AbstractAutoProxyCreator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,11 +20,8 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.aopalliance.aop.Advice; @@ -136,15 +133,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig private BeanFactory beanFactory; - private final Set targetSourcedBeans = Collections.synchronizedSet(new HashSet()); + private final Map advisedBeans = new ConcurrentHashMap(64); - private final Set earlyProxyReferences = Collections.synchronizedSet(new HashSet()); + // using a ConcurrentHashMap as a Set + private final Map targetSourcedBeans = new ConcurrentHashMap(16); - private final Set advisedBeans = Collections.synchronizedSet(new HashSet()); + // using a ConcurrentHashMap as a Set + private final Map earlyProxyReferences = new ConcurrentHashMap(16); - private final Set nonAdvisedBeans = Collections.synchronizedSet(new HashSet()); - - private final Map> proxyTypes = new ConcurrentHashMap>(); + private final Map> proxyTypes = new ConcurrentHashMap>(16); /** @@ -264,19 +261,19 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { Object cacheKey = getCacheKey(bean.getClass(), beanName); - this.earlyProxyReferences.add(cacheKey); + this.earlyProxyReferences.put(cacheKey, Boolean.TRUE); return wrapIfNecessary(bean, beanName, cacheKey); } public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); - if (!this.targetSourcedBeans.contains(cacheKey)) { - if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) { + if (!this.targetSourcedBeans.containsKey(beanName)) { + if (this.advisedBeans.containsKey(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { - this.nonAdvisedBeans.add(cacheKey); + this.advisedBeans.put(cacheKey, Boolean.FALSE); return null; } } @@ -286,7 +283,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig // The TargetSource will handle target instances in a custom fashion. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { - this.targetSourcedBeans.add(beanName); + this.targetSourcedBeans.put(beanName, Boolean.TRUE); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); @@ -318,7 +315,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); - if (!this.earlyProxyReferences.contains(cacheKey)) { + if (!this.earlyProxyReferences.containsKey(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } @@ -344,27 +341,27 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig * @return a proxy wrapping the bean, or the raw bean instance as-is */ protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { - if (this.targetSourcedBeans.contains(beanName)) { + if (this.targetSourcedBeans.containsKey(beanName)) { return bean; } - if (this.nonAdvisedBeans.contains(cacheKey)) { + if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { - this.nonAdvisedBeans.add(cacheKey); + this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { - this.advisedBeans.add(cacheKey); + this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } - this.nonAdvisedBeans.add(cacheKey); + this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } diff --git a/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java b/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java index ab6f213471b..6048f7b4846 100644 --- a/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java +++ b/spring-aop/src/main/java/org/springframework/aop/target/ThreadLocalTargetSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package org.springframework.aop.target; -import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -62,7 +61,7 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource /** * Set of managed targets, enabling us to keep track of the targets we've created. */ - private final Set targetSet = Collections.synchronizedSet(new HashSet()); + private final Set targetSet = new HashSet(); private int invocationCount; @@ -85,7 +84,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource // Associate target with ThreadLocal. target = newPrototypeInstance(); this.targetInThread.set(target); - this.targetSet.add(target); + synchronized (this.targetSet) { + this.targetSet.add(target); + } } else { ++this.hitCount; @@ -119,7 +120,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource } public int getObjectCount() { - return this.targetSet.size(); + synchronized (this.targetSet) { + return this.targetSet.size(); + } } diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java index dcbe5a54e51..8c82e9ed51d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -57,6 +57,7 @@ public abstract class BeanUtils { private static final Log logger = LogFactory.getLog(BeanUtils.class); + // using WeakHashMap as a Set private static final Map, Boolean> unknownEditorTypes = Collections.synchronizedMap(new WeakHashMap, Boolean>()); diff --git a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java index 91ef2ac914a..2e9dde90b88 100644 --- a/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java +++ b/spring-beans/src/main/java/org/springframework/beans/CachedIntrospectionResults.java @@ -22,7 +22,6 @@ import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.ref.Reference; import java.lang.ref.WeakReference; -import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; @@ -70,14 +69,14 @@ public class CachedIntrospectionResults { * Set of ClassLoaders that this CachedIntrospectionResults class will always * accept classes from, even if the classes do not qualify as cache-safe. */ - static final Set acceptedClassLoaders = Collections.synchronizedSet(new HashSet()); + static final Set acceptedClassLoaders = new HashSet(); /** * Map keyed by class containing CachedIntrospectionResults. * Needs to be a WeakHashMap with WeakReferences as values to allow * for proper garbage collection in case of multiple class loaders. */ - static final Map classCache = Collections.synchronizedMap(new WeakHashMap()); + static final Map classCache = new WeakHashMap(); /** @@ -94,7 +93,9 @@ public class CachedIntrospectionResults { */ public static void acceptClassLoader(ClassLoader classLoader) { if (classLoader != null) { - acceptedClassLoaders.add(classLoader); + synchronized (acceptedClassLoaders) { + acceptedClassLoaders.add(classLoader); + } } } @@ -137,7 +138,10 @@ public class CachedIntrospectionResults { */ static CachedIntrospectionResults forClass(Class beanClass) throws BeansException { CachedIntrospectionResults results; - Object value = classCache.get(beanClass); + Object value; + synchronized (classCache) { + value = classCache.get(beanClass); + } if (value instanceof Reference) { Reference ref = (Reference) value; results = (CachedIntrospectionResults) ref.get(); @@ -149,14 +153,18 @@ public class CachedIntrospectionResults { if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) || isClassLoaderAccepted(beanClass.getClassLoader())) { results = new CachedIntrospectionResults(beanClass); - classCache.put(beanClass, results); + synchronized (classCache) { + classCache.put(beanClass, results); + } } else { if (logger.isDebugEnabled()) { logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe"); } results = new CachedIntrospectionResults(beanClass); - classCache.put(beanClass, new WeakReference(results)); + synchronized (classCache) { + classCache.put(beanClass, new WeakReference(results)); + } } } return results; @@ -172,8 +180,10 @@ public class CachedIntrospectionResults { private static boolean isClassLoaderAccepted(ClassLoader classLoader) { // Iterate over array copy in order to avoid synchronization for the entire // ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator). - ClassLoader[] acceptedLoaderArray = - acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]); + ClassLoader[] acceptedLoaderArray; + synchronized (acceptedClassLoaders) { + acceptedLoaderArray = acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]); + } for (ClassLoader registeredLoader : acceptedLoaderArray) { if (isUnderneathClassLoader(classLoader, registeredLoader)) { return true; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java index bd7bbe2357b..4d0b8b5bbfb 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java @@ -119,10 +119,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean private ConfigurableListableBeanFactory beanFactory; private final Map, Constructor[]> candidateConstructorsCache = - new ConcurrentHashMap, Constructor[]>(); + new ConcurrentHashMap, Constructor[]>(64); private final Map, InjectionMetadata> injectionMetadataCache = - new ConcurrentHashMap, InjectionMetadata>(); + new ConcurrentHashMap, InjectionMetadata>(64); /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java index 50503e0d35e..74a5e59d240 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InitDestroyAnnotationBeanPostProcessor.java @@ -24,8 +24,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Map; @@ -85,7 +83,7 @@ public class InitDestroyAnnotationBeanPostProcessor private int order = Ordered.LOWEST_PRECEDENCE; private transient final Map, LifecycleMetadata> lifecycleMetadataCache = - new ConcurrentHashMap, LifecycleMetadata>(); + new ConcurrentHashMap, LifecycleMetadata>(64); /** @@ -240,69 +238,57 @@ public class InitDestroyAnnotationBeanPostProcessor */ private class LifecycleMetadata { - private final Set initMethods; + private final Class targetClass; - private final Set destroyMethods; + private final Collection initMethods; + + private final Collection destroyMethods; + + private volatile Set checkedInitMethods; + + private volatile Set checkedDestroyMethods; public LifecycleMetadata(Class targetClass, Collection initMethods, Collection destroyMethods) { - if (!initMethods.isEmpty()) { - this.initMethods = Collections.synchronizedSet(new LinkedHashSet(initMethods.size())); - for (LifecycleElement element : initMethods) { - if (logger.isDebugEnabled()) { - logger.debug("Found init method on class [" + targetClass.getName() + "]: " + element); - } - this.initMethods.add(element); - } - } - else { - this.initMethods = Collections.emptySet(); - } - - if (!destroyMethods.isEmpty()) { - this.destroyMethods = Collections.synchronizedSet(new LinkedHashSet(destroyMethods.size())); - for (LifecycleElement element : destroyMethods) { - if (logger.isDebugEnabled()) { - logger.debug("Found destroy method on class [" + targetClass.getName() + "]: " + element); - } - this.destroyMethods.add(element); - } - } - else { - this.destroyMethods = Collections.emptySet(); - } + this.targetClass = targetClass; + this.initMethods = initMethods; + this.destroyMethods = destroyMethods; } public void checkConfigMembers(RootBeanDefinition beanDefinition) { - synchronized(this.initMethods) { - for (Iterator it = this.initMethods.iterator(); it.hasNext();) { - String methodIdentifier = it.next().getIdentifier(); - if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) { - beanDefinition.registerExternallyManagedInitMethod(methodIdentifier); - } - else { - it.remove(); + Set checkedInitMethods = new LinkedHashSet(this.initMethods.size()); + for (LifecycleElement element : this.initMethods) { + String methodIdentifier = element.getIdentifier(); + if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) { + beanDefinition.registerExternallyManagedInitMethod(methodIdentifier); + checkedInitMethods.add(element); + if (logger.isDebugEnabled()) { + logger.debug("Registered init method on class [" + this.targetClass.getName() + "]: " + element); } } } - synchronized(this.destroyMethods) { - for (Iterator it = this.destroyMethods.iterator(); it.hasNext();) { - String methodIdentifier = it.next().getIdentifier(); - if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) { - beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier); - } - else { - it.remove(); + Set checkedDestroyMethods = new LinkedHashSet(this.destroyMethods.size()); + for (LifecycleElement element : this.destroyMethods) { + String methodIdentifier = element.getIdentifier(); + if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) { + beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier); + checkedDestroyMethods.add(element); + if (logger.isDebugEnabled()) { + logger.debug("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element); } } } + this.checkedInitMethods = checkedInitMethods; + this.checkedDestroyMethods = checkedDestroyMethods; } public void invokeInitMethods(Object target, String beanName) throws Throwable { - if (!this.initMethods.isEmpty()) { + Collection initMethodsToIterate = + (this.checkedInitMethods != null ? this.checkedInitMethods : this.initMethods); + if (!initMethodsToIterate.isEmpty()) { boolean debug = logger.isDebugEnabled(); - for (LifecycleElement element : this.initMethods) { + for (LifecycleElement element : initMethodsToIterate) { if (debug) { logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod()); } @@ -312,9 +298,11 @@ public class InitDestroyAnnotationBeanPostProcessor } public void invokeDestroyMethods(Object target, String beanName) throws Throwable { - if (!this.destroyMethods.isEmpty()) { + Collection destroyMethodsToIterate = + (this.checkedDestroyMethods != null ? this.checkedDestroyMethods : this.destroyMethods); + if (!destroyMethodsToIterate.isEmpty()) { boolean debug = logger.isDebugEnabled(); - for (LifecycleElement element : this.destroyMethods) { + for (LifecycleElement element : destroyMethodsToIterate) { if (debug) { logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod()); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java index c7fa84a72a4..fe3e3b15efd 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/InjectionMetadata.java @@ -22,8 +22,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.util.Collection; -import java.util.Collections; -import java.util.Iterator; import java.util.LinkedHashSet; import java.util.Set; @@ -50,42 +48,39 @@ public class InjectionMetadata { private final Log logger = LogFactory.getLog(InjectionMetadata.class); - private final Set injectedElements; + private final Class targetClass; + + private final Collection injectedElements; + + private volatile Set checkedElements; public InjectionMetadata(Class targetClass, Collection elements) { - if (!elements.isEmpty()) { - this.injectedElements = Collections.synchronizedSet(new LinkedHashSet(elements.size())); - for (InjectedElement element : elements) { - if (logger.isDebugEnabled()) { - logger.debug("Found injected element on class [" + targetClass.getName() + "]: " + element); - } - this.injectedElements.add(element); - } - } - else { - this.injectedElements = Collections.emptySet(); - } + this.targetClass = targetClass; + this.injectedElements = elements; } public void checkConfigMembers(RootBeanDefinition beanDefinition) { - synchronized (this.injectedElements) { - for (Iterator it = this.injectedElements.iterator(); it.hasNext();) { - Member member = it.next().getMember(); - if (!beanDefinition.isExternallyManagedConfigMember(member)) { - beanDefinition.registerExternallyManagedConfigMember(member); - } - else { - it.remove(); + Set checkedElements = new LinkedHashSet(this.injectedElements.size()); + for (InjectedElement element : this.injectedElements) { + Member member = element.getMember(); + if (!beanDefinition.isExternallyManagedConfigMember(member)) { + beanDefinition.registerExternallyManagedConfigMember(member); + checkedElements.add(element); + if (logger.isDebugEnabled()) { + logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element); } } } + this.checkedElements = checkedElements; } public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable { - if (!this.injectedElements.isEmpty()) { + Collection elementsToIterate = + (this.checkedElements != null ? this.checkedElements : this.injectedElements); + if (!elementsToIterate.isEmpty()) { boolean debug = logger.isDebugEnabled(); - for (InjectedElement element : this.injectedElements) { + for (InjectedElement element : elementsToIterate) { if (debug) { logger.debug("Processing injected method of bean '" + beanName + "': " + element); } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java index 8399f25f747..e4db17e1eb5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/annotation/RequiredAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,10 +20,9 @@ import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Set; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; @@ -89,8 +88,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP private ConfigurableListableBeanFactory beanFactory; - /** Cache for validated bean names, skipping re-validation for the same bean */ - private final Set validatedBeanNames = Collections.synchronizedSet(new HashSet()); + /** + * Cache for validated bean names, skipping re-validation for the same bean + * (using a ConcurrentHashMap as a Set) + */ + private final Map validatedBeanNames = new ConcurrentHashMap(64); /** @@ -137,7 +139,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { - if (!this.validatedBeanNames.contains(beanName)) { + if (!this.validatedBeanNames.containsKey(beanName)) { if (!shouldSkip(this.beanFactory, beanName)) { List invalidProperties = new ArrayList(); for (PropertyDescriptor pd : pds) { @@ -149,7 +151,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName)); } } - this.validatedBeanNames.add(beanName); + this.validatedBeanNames.put(beanName, Boolean.TRUE); } return pvs; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java index 7d2125c66cb..736a7d14fd5 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/config/PropertyOverrideConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,10 @@ package org.springframework.beans.factory.config; -import java.util.Collections; import java.util.Enumeration; -import java.util.HashSet; +import java.util.Map; import java.util.Properties; -import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValue; @@ -71,8 +70,11 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { private boolean ignoreInvalidKeys = false; - /** Contains names of beans that have overrides */ - private Set beanNames = Collections.synchronizedSet(new HashSet()); + /** + * Contains names of beans that have overrides + * (using a ConcurrentHashMap as a Set) + */ + private Map beanNames = new ConcurrentHashMap(16); /** @@ -128,7 +130,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { } String beanName = key.substring(0, separatorIndex); String beanProperty = key.substring(separatorIndex+1); - this.beanNames.add(beanName); + this.beanNames.put(beanName, Boolean.TRUE); applyPropertyValue(factory, beanName, beanProperty, value); if (logger.isDebugEnabled()) { logger.debug("Property '" + key + "' set to value [" + value + "]"); @@ -159,7 +161,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer { * the named bean */ public boolean hasPropertyOverridesFor(String beanName) { - return this.beanNames.contains(beanName); + return this.beanNames.containsKey(beanName); } } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 4d34639919e..1cf82fc6904 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -145,11 +145,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac /** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */ private final Map factoryBeanInstanceCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(16); /** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */ private final Map filteredPropertyDescriptorsCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 2919622977f..b5699c2fb87 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -24,7 +24,6 @@ import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; @@ -151,17 +150,20 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp private boolean hasDestructionAwareBeanPostProcessors; /** Map from scope identifier String to corresponding Scope */ - private final Map scopes = new HashMap(); + private final Map scopes = new HashMap(8); /** Security context used when running with a SecurityManager */ private SecurityContextProvider securityContextProvider; /** Map from bean name to merged RootBeanDefinition */ private final Map mergedBeanDefinitions = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); - /** Names of beans that have already been created at least once */ - private final Set alreadyCreated = Collections.synchronizedSet(new HashSet()); + /** + * Names of beans that have already been created at least once + * (using a ConcurrentHashMap as a Set) + */ + private final Map alreadyCreated = new ConcurrentHashMap(64); /** Names of beans that are currently in creation */ private final ThreadLocal prototypesCurrentlyInCreation = @@ -1372,7 +1374,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * @param beanName the name of the bean */ protected void markBeanAsCreated(String beanName) { - this.alreadyCreated.add(beanName); + this.alreadyCreated.put(beanName, Boolean.TRUE); } /** @@ -1383,7 +1385,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * at this point already */ protected boolean isBeanEligibleForMetadataCaching(String beanName) { - return this.alreadyCreated.contains(beanName); + return this.alreadyCreated.containsKey(beanName); } /** @@ -1393,7 +1395,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * @return true if actually removed, false otherwise */ protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) { - if (!this.alreadyCreated.contains(beanName)) { + if (!this.alreadyCreated.containsKey(beanName)) { removeSingleton(beanName); return true; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 30408822f71..3dfa8e893e4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -112,7 +112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto /** Map from serialized id to factory instance */ private static final Map> serializableFactories = - new ConcurrentHashMap>(); + new ConcurrentHashMap>(8); /** Optional id for this factory, for serialization purposes */ private String serializationId; @@ -127,16 +127,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver(); /** Map from dependency type to corresponding autowired value */ - private final Map, Object> resolvableDependencies = new HashMap, Object>(); + private final Map, Object> resolvableDependencies = new HashMap, Object>(16); /** Map of bean definition objects, keyed by bean name */ - private final Map beanDefinitionMap = new ConcurrentHashMap(); + private final Map beanDefinitionMap = new ConcurrentHashMap(64); /** Map of singleton bean names keyed by bean class */ - private final Map, String[]> singletonBeanNamesByType = new ConcurrentHashMap, String[]>(); + private final Map, String[]> singletonBeanNamesByType = new ConcurrentHashMap, String[]>(64); /** Map of non-singleton bean names keyed by bean class */ - private final Map, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap, String[]>(); + private final Map, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap, String[]>(64); /** List of bean definition names, in registration order */ private final List beanDefinitionNames = new ArrayList(); diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java index 43564d4d51b..64346bd9f2c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -81,22 +81,22 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements protected final Log logger = LogFactory.getLog(getClass()); /** Cache of singleton objects: bean name --> bean instance */ - private final Map singletonObjects = new ConcurrentHashMap(); + private final Map singletonObjects = new ConcurrentHashMap(64); /** Cache of singleton factories: bean name --> ObjectFactory */ - private final Map singletonFactories = new HashMap(); + private final Map singletonFactories = new HashMap(16); /** Cache of early singleton objects: bean name --> bean instance */ - private final Map earlySingletonObjects = new HashMap(); + private final Map earlySingletonObjects = new HashMap(16); /** Set of registered singletons, containing the bean names in registration order */ - private final Set registeredSingletons = new LinkedHashSet(16); + private final Set registeredSingletons = new LinkedHashSet(64); /** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */ - private final Map singletonsCurrentlyInCreation = new ConcurrentHashMap(); + private final Map singletonsCurrentlyInCreation = new ConcurrentHashMap(16); /** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */ - private final Map inCreationCheckExclusions = new ConcurrentHashMap(); + private final Map inCreationCheckExclusions = new ConcurrentHashMap(16); /** List of suppressed Exceptions, available for associating related causes */ private Set suppressedExceptions; @@ -108,13 +108,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements private final Map disposableBeans = new LinkedHashMap(); /** Map between containing bean names: bean name --> Set of bean names that the bean contains */ - private final Map> containedBeanMap = new ConcurrentHashMap>(); + private final Map> containedBeanMap = new ConcurrentHashMap>(16); /** Map between dependent bean names: bean name --> Set of dependent bean names */ - private final Map> dependentBeanMap = new ConcurrentHashMap>(); + private final Map> dependentBeanMap = new ConcurrentHashMap>(64); /** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */ - private final Map> dependenciesForBeanMap = new ConcurrentHashMap>(); + private final Map> dependenciesForBeanMap = new ConcurrentHashMap>(64); public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java index 8633dda8d44..9517497ac9b 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryBeanRegistrySupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ import org.springframework.beans.factory.FactoryBeanNotInitializedException; public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry { /** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */ - private final Map factoryBeanObjectCache = new ConcurrentHashMap(); + private final Map factoryBeanObjectCache = new ConcurrentHashMap(16); /** diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java index 808b4f57159..aaa65972758 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/RootBeanDefinition.java @@ -18,9 +18,8 @@ package org.springframework.beans.factory.support; import java.lang.reflect.Member; import java.lang.reflect.Method; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanDefinition; @@ -48,11 +47,14 @@ import org.springframework.util.Assert; */ public class RootBeanDefinition extends AbstractBeanDefinition { - private final Set externallyManagedConfigMembers = Collections.synchronizedSet(new HashSet(0)); + // using a ConcurrentHashMap as a Set + private final Map externallyManagedConfigMembers = new ConcurrentHashMap(0); - private final Set externallyManagedInitMethods = Collections.synchronizedSet(new HashSet(0)); + // using a ConcurrentHashMap as a Set + private final Map externallyManagedInitMethods = new ConcurrentHashMap(0); - private final Set externallyManagedDestroyMethods = Collections.synchronizedSet(new HashSet(0)); + // using a ConcurrentHashMap as a Set + private final Map externallyManagedDestroyMethods = new ConcurrentHashMap(0); private BeanDefinitionHolder decoratedDefinition; @@ -277,27 +279,27 @@ public class RootBeanDefinition extends AbstractBeanDefinition { public void registerExternallyManagedConfigMember(Member configMember) { - this.externallyManagedConfigMembers.add(configMember); + this.externallyManagedConfigMembers.put(configMember, Boolean.TRUE); } public boolean isExternallyManagedConfigMember(Member configMember) { - return this.externallyManagedConfigMembers.contains(configMember); + return this.externallyManagedConfigMembers.containsKey(configMember); } public void registerExternallyManagedInitMethod(String initMethod) { - this.externallyManagedInitMethods.add(initMethod); + this.externallyManagedInitMethods.put(initMethod, Boolean.TRUE); } public boolean isExternallyManagedInitMethod(String initMethod) { - return this.externallyManagedInitMethods.contains(initMethod); + return this.externallyManagedInitMethods.containsKey(initMethod); } public void registerExternallyManagedDestroyMethod(String destroyMethod) { - this.externallyManagedDestroyMethods.add(destroyMethod); + this.externallyManagedDestroyMethods.put(destroyMethod, Boolean.TRUE); } public boolean isExternallyManagedDestroyMethod(String destroyMethod) { - return this.externallyManagedDestroyMethods.contains(destroyMethod); + return this.externallyManagedDestroyMethods.containsKey(destroyMethod); } public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) { diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java index 4b9c0aecd29..8a42fc233e1 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/SimpleBeanDefinitionRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,7 +37,7 @@ import org.springframework.util.StringUtils; public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry { /** Map of bean definition objects, keyed by bean name */ - private final Map beanDefinitionMap = new ConcurrentHashMap(); + private final Map beanDefinitionMap = new ConcurrentHashMap(64); public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.java index dd9b791898d..56fe15eb80c 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/DefaultNamespaceHandlerResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -155,7 +155,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver if (logger.isDebugEnabled()) { logger.debug("Loaded NamespaceHandler mappings: " + mappings); } - Map handlerMappings = new ConcurrentHashMap(); + Map handlerMappings = new ConcurrentHashMap(mappings.size()); CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings); this.handlerMappings = handlerMappings; } diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java index f2fb4bfe167..d4f1f1bbf62 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/xml/PluggableSchemaResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -145,7 +145,7 @@ public class PluggableSchemaResolver implements EntityResolver { if (logger.isDebugEnabled()) { logger.debug("Loaded schema mappings: " + mappings); } - Map schemaMappings = new ConcurrentHashMap(); + Map schemaMappings = new ConcurrentHashMap(mappings.size()); CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings); this.schemaMappings = schemaMappings; } diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java index 270435f3018..0da4c6850bc 100644 --- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java +++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCache.java @@ -56,7 +56,7 @@ public class ConcurrentMapCache implements Cache { * @param name the name of the cache */ public ConcurrentMapCache(String name) { - this(name, new ConcurrentHashMap(), true); + this(name, new ConcurrentHashMap(256), true); } /** @@ -65,7 +65,7 @@ public class ConcurrentMapCache implements Cache { * @param allowNullValues whether to accept and convert null values for this cache */ public ConcurrentMapCache(String name, boolean allowNullValues) { - this(name, new ConcurrentHashMap(), allowNullValues); + this(name, new ConcurrentHashMap(256), allowNullValues); } /** diff --git a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java index fd59da23c8a..7a0067a329b 100644 --- a/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/concurrent/ConcurrentMapCacheManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ import org.springframework.cache.CacheManager; */ public class ConcurrentMapCacheManager implements CacheManager { - private final ConcurrentMap cacheMap = new ConcurrentHashMap(); + private final ConcurrentMap cacheMap = new ConcurrentHashMap(16); private boolean dynamic = true; diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java index ff0dbc0eeda..978dbd8c364 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/AbstractFallbackCacheOperationSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.BridgeMethodResolver; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; @@ -48,6 +49,7 @@ import org.springframework.util.ObjectUtils; * configurable. * * @author Costin Leau + * @author Juergen Hoeller * @since 3.1 */ public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource { @@ -70,7 +72,8 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera *

As this base class is not marked Serializable, the cache will be recreated * after serialization - provided that the concrete subclass is Serializable. */ - final Map> attributeCache = new ConcurrentHashMap>(); + final Map> attributeCache = + new ConcurrentHashMap>(1024); /** diff --git a/spring-context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java b/spring-context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java index 3e989408d4d..2ee38bb8728 100644 --- a/spring-context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java +++ b/spring-context/src/main/java/org/springframework/cache/interceptor/ExpressionEvaluator.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,16 +39,16 @@ import org.springframework.expression.spel.standard.SpelExpressionParser; */ class ExpressionEvaluator { - private SpelExpressionParser parser = new SpelExpressionParser(); + private final SpelExpressionParser parser = new SpelExpressionParser(); // shared param discoverer since it caches data internally - private ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); + private final ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); - private Map conditionCache = new ConcurrentHashMap(); + private final Map conditionCache = new ConcurrentHashMap(64); - private Map keyCache = new ConcurrentHashMap(); + private final Map keyCache = new ConcurrentHashMap(64); - private Map targetMethodCache = new ConcurrentHashMap(); + private final Map targetMethodCache = new ConcurrentHashMap(64); public EvaluationContext createEvaluationContext( diff --git a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java index e5665734b92..5d301d85f4c 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/AbstractCacheManager.java @@ -29,9 +29,8 @@ import org.springframework.cache.CacheManager; import org.springframework.util.Assert; /** - * Abstract base class implementing the common {@link CacheManager} - * methods. Useful for 'static' environments where the backing caches do - * not change. + * Abstract base class implementing the common {@link CacheManager} methods. + * Useful for 'static' environments where the backing caches do not change. * * @author Costin Leau * @author Juergen Hoeller @@ -39,9 +38,9 @@ import org.springframework.util.Assert; */ public abstract class AbstractCacheManager implements CacheManager, InitializingBean { - private final ConcurrentMap cacheMap = new ConcurrentHashMap(); + private final ConcurrentMap cacheMap = new ConcurrentHashMap(16); - private Set cacheNames = new LinkedHashSet(); + private Set cacheNames = new LinkedHashSet(16); public void afterPropertiesSet() { diff --git a/spring-context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java b/spring-context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java index 32ffb8192fa..dc3203e6cf8 100644 --- a/spring-context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java +++ b/spring-context/src/main/java/org/springframework/cache/support/NoOpCacheManager.java @@ -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"); * you may not use this file except in compliance with the License. @@ -39,8 +39,36 @@ import org.springframework.cache.CacheManager; */ public class NoOpCacheManager implements CacheManager { - private final ConcurrentMap caches = new ConcurrentHashMap(); - private Set names = new LinkedHashSet(); + private final ConcurrentMap caches = new ConcurrentHashMap(16); + + private final Set cacheNames = new LinkedHashSet(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 getCacheNames() { + synchronized (this.cacheNames) { + return Collections.unmodifiableSet(this.cacheNames); + } + } + private static class NoOpCache implements Cache { @@ -61,7 +89,7 @@ public class NoOpCacheManager implements CacheManager { } public String getName() { - return name; + return this.name; } public Object getNativeCache() { @@ -72,30 +100,4 @@ public class NoOpCacheManager implements CacheManager { } } - /** - * {@inheritDoc} - * - * This implementation always returns a {@link Cache} implementation that will not - * store items. Additionally, the request cache will be remembered by the manager for consistency. - */ - public Cache getCache(String name) { - Cache cache = caches.get(name); - if (cache == null) { - caches.putIfAbsent(name, new NoOpCache(name)); - synchronized (names) { - names.add(name); - } - } - - return caches.get(name); - } - - /** - * {@inheritDoc} - * - * This implementation returns the name of the caches previously requested. - */ - public Collection getCacheNames() { - return Collections.unmodifiableSet(names); - } } diff --git a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java index 91396d45347..295ebb500f8 100644 --- a/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java +++ b/spring-context/src/main/java/org/springframework/context/annotation/CommonAnnotationBeanPostProcessor.java @@ -178,7 +178,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean private transient BeanFactory beanFactory; private transient final Map, InjectionMetadata> injectionMetadataCache = - new ConcurrentHashMap, InjectionMetadata>(); + new ConcurrentHashMap, InjectionMetadata>(64); /** @@ -513,10 +513,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean protected boolean shareable = true; - private volatile boolean cached = false; - - private volatile Object cachedFieldValue; - public ResourceElement(Member member, PropertyDescriptor pd) { super(member, pd); } diff --git a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java index 40ebd207596..055b5e59db8 100644 --- a/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java +++ b/spring-context/src/main/java/org/springframework/context/event/AbstractApplicationEventMulticaster.java @@ -53,7 +53,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application private final ListenerRetriever defaultRetriever = new ListenerRetriever(false); private final Map retrieverCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); private BeanFactory beanFactory; diff --git a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java index 80b546f2e67..8537e050876 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java +++ b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,10 +60,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver { private ExpressionParser expressionParser = new SpelExpressionParser(); - private final Map expressionCache = new ConcurrentHashMap(); + private final Map expressionCache = new ConcurrentHashMap(256); private final Map evaluationCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(8); private final ParserContext beanExpressionParserContext = new ParserContext() { public boolean isTemplate() { diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index 9e2508ea787..b1e7726ed6f 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1387,7 +1387,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader */ private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor { - private final Map singletonNames = new ConcurrentHashMap(); + private final Map singletonNames = new ConcurrentHashMap(64); public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class beanType, String beanName) { if (beanDefinition.isSingleton()) { diff --git a/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java b/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java index cb6aa8623cd..345131a5aa4 100644 --- a/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java +++ b/spring-context/src/main/java/org/springframework/format/support/FormattingConversionService.java @@ -53,10 +53,10 @@ public class FormattingConversionService extends GenericConversionService private StringValueResolver embeddedValueResolver; private final Map cachedPrinters = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); private final Map cachedParsers = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); public void setEmbeddedValueResolver(StringValueResolver resolver) { @@ -214,11 +214,14 @@ public class FormattingConversionService extends GenericConversionService return sourceType.hasAnnotation(annotationType); } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - AnnotationConverterKey converterKey = new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType()); + AnnotationConverterKey converterKey = + new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType()); GenericConverter converter = cachedPrinters.get(converterKey); if (converter == null) { - Printer printer = annotationFormatterFactory.getPrinter(converterKey.getAnnotation(), converterKey.getFieldType()); + Printer printer = annotationFormatterFactory.getPrinter( + converterKey.getAnnotation(), converterKey.getFieldType()); converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this); cachedPrinters.put(converterKey, converter); } @@ -226,7 +229,8 @@ public class FormattingConversionService extends GenericConversionService } public String toString() { - return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + String.class.getName() + ": " + annotationFormatterFactory; + return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + + String.class.getName() + ": " + annotationFormatterFactory; } } @@ -254,11 +258,14 @@ public class FormattingConversionService extends GenericConversionService return targetType.hasAnnotation(annotationType); } + @SuppressWarnings("unchecked") public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) { - AnnotationConverterKey converterKey = new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType()); + AnnotationConverterKey converterKey = + new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType()); GenericConverter converter = cachedParsers.get(converterKey); if (converter == null) { - Parser parser = annotationFormatterFactory.getParser(converterKey.getAnnotation(), converterKey.getFieldType()); + Parser parser = annotationFormatterFactory.getParser( + converterKey.getAnnotation(), converterKey.getFieldType()); converter = new ParserConverter(fieldType, parser, FormattingConversionService.this); cachedParsers.put(converterKey, converter); } @@ -266,7 +273,8 @@ public class FormattingConversionService extends GenericConversionService } public String toString() { - return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName() + ": " + annotationFormatterFactory; + return String.class.getName() + " -> @" + annotationType.getName() + " " + + fieldType.getName() + ": " + annotationFormatterFactory; } } diff --git a/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java b/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java index b8526280724..b29478ebc07 100644 --- a/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java +++ b/spring-core/src/main/java/org/springframework/core/LocalVariableTableParameterNameDiscoverer.java @@ -42,10 +42,9 @@ import org.springframework.util.ClassUtils; * information in the method attributes to discover parameter names. Returns * null if the class file was compiled without debug information. * - *

Uses ObjectWeb's ASM library for analyzing class files. Each discoverer - * instance caches the ASM discovered information for each introspected Class, in a - * thread-safe manner. It is recommended to reuse discoverer instances - * as far as possible. + *

Uses ObjectWeb's ASM library for analyzing class files. Each discoverer instance + * caches the ASM discovered information for each introspected Class, in a thread-safe + * manner. It is recommended to reuse ParameterNameDiscoverer instances as far as possible. * * @author Adrian Colyer * @author Costin Leau @@ -62,7 +61,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD // the cache uses a nested index (value is a map) to keep the top level cache relatively small in size private final Map, Map> parameterNamesCache = - new ConcurrentHashMap, Map>(); + new ConcurrentHashMap, Map>(32); public String[] getParameterNames(Method method) { @@ -111,7 +110,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD } try { ClassReader classReader = new ClassReader(is); - Map map = new ConcurrentHashMap(); + Map map = new ConcurrentHashMap(32); classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0); return map; } diff --git a/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java b/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java index 971906fc781..649276ebad6 100644 --- a/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java +++ b/spring-core/src/main/java/org/springframework/core/SimpleAliasRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,7 +38,7 @@ import org.springframework.util.StringValueResolver; public class SimpleAliasRegistry implements AliasRegistry { /** Map from alias to canonical name */ - private final Map aliasMap = new ConcurrentHashMap(); + private final Map aliasMap = new ConcurrentHashMap(16); public void registerAlias(String name, String alias) { diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java index cf08663d38a..3e69ee4421c 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/GenericConversionService.java @@ -74,7 +74,7 @@ public class GenericConversionService implements ConfigurableConversionService { private final Converters converters = new Converters(); private final Map converterCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(64); // implementing ConverterRegistry @@ -182,8 +182,8 @@ public class GenericConversionService implements ConfigurableConversionService { * @param targetType the target type * @return the converted value * @throws ConversionException if a conversion exception occurred - * @throws IllegalArgumentException if targetType is null - * @throws IllegalArgumentException if sourceType is null but source is not null + * @throws IllegalArgumentException if targetType is null, + * or sourceType is null but source is not null */ public Object convert(Object source, TypeDescriptor targetType) { return convert(source, TypeDescriptor.forObject(source), targetType); @@ -480,7 +480,6 @@ public class GenericConversionService implements ConfigurableConversionService { * @param sourceType the source type * @param targetType the target type * @return a {@link GenericConverter} or null - * @see #getTypeHierarchy(Class) */ public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) { // Search the full type hierarchy diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java index 81f60416b0c..c8f7f51e8de 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectivePropertyAccessor.java @@ -46,11 +46,11 @@ import org.springframework.util.StringUtils; */ public class ReflectivePropertyAccessor implements PropertyAccessor { - private final Map readerCache = new ConcurrentHashMap(); + private final Map readerCache = new ConcurrentHashMap(64); - private final Map writerCache = new ConcurrentHashMap(); + private final Map writerCache = new ConcurrentHashMap(64); - private final Map typeDescriptorCache = new ConcurrentHashMap(); + private final Map typeDescriptorCache = new ConcurrentHashMap(64); /** @@ -86,7 +86,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { Field field = findField(name, type, target); if (field != null) { TypeDescriptor typeDescriptor = new TypeDescriptor(field); - this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor)); + this.readerCache.put(cacheKey, new InvokerPair(field, typeDescriptor)); this.typeDescriptorCache.put(cacheKey, typeDescriptor); return true; } @@ -264,15 +264,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor { return TypeDescriptor.valueOf(Integer.TYPE); } CacheKey cacheKey = new CacheKey(type, name); - TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); + TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey); if (typeDescriptor == null) { // attempt to populate the cache entry try { if (canRead(context, target, name)) { - typeDescriptor = this.typeDescriptorCache.get(cacheKey); + typeDescriptor = this.typeDescriptorCache.get(cacheKey); } else if (canWrite(context, target, name)) { - typeDescriptor = this.typeDescriptorCache.get(cacheKey); + typeDescriptor = this.typeDescriptorCache.get(cacheKey); } } catch (AccessException ex) { diff --git a/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java b/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java index 7fe9de19d0d..351a7807c6d 100644 --- a/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java +++ b/spring-jms/src/main/java/org/springframework/jms/support/destination/JndiDestinationResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ public class JndiDestinationResolver extends JndiLocatorSupport implements Cachi private DestinationResolver dynamicDestinationResolver = new DynamicDestinationResolver(); - private final Map destinationCache = new ConcurrentHashMap(); + private final Map destinationCache = new ConcurrentHashMap(16); /** diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java index ebcde69b3b6..a3622f033ad 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionHolder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +16,8 @@ package org.springframework.orm.hibernate3; -import java.util.Collections; -import java.util.HashMap; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.hibernate.FlushMode; import org.hibernate.Session; @@ -44,10 +43,10 @@ public class SessionHolder extends ResourceHolderSupport { private static final Object DEFAULT_KEY = new Object(); /** - * This Map needs to be synchronized because there might be multi-threaded + * This Map needs to be concurrent because there might be multi-threaded * access in the case of JTA with remote transaction propagation. */ - private final Map sessionMap = Collections.synchronizedMap(new HashMap(1)); + private final Map sessionMap = new ConcurrentHashMap(1); private Transaction transaction; @@ -89,12 +88,10 @@ public class SessionHolder extends ResourceHolderSupport { } public Session getAnySession() { - synchronized (this.sessionMap) { - if (!this.sessionMap.isEmpty()) { - return this.sessionMap.values().iterator().next(); - } - return null; + if (!this.sessionMap.isEmpty()) { + return this.sessionMap.values().iterator().next(); } + return null; } public void addSession(Session session) { @@ -120,10 +117,8 @@ public class SessionHolder extends ResourceHolderSupport { } public boolean doesNotHoldNonDefaultSession() { - synchronized (this.sessionMap) { - return this.sessionMap.isEmpty() || - (this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY)); - } + return this.sessionMap.isEmpty() || + (this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY)); } diff --git a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java index ff11c6383a2..bba586e14c5 100644 --- a/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java +++ b/spring-orm/src/main/java/org/springframework/orm/jpa/support/PersistenceAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -182,10 +182,10 @@ public class PersistenceAnnotationBeanPostProcessor private transient ListableBeanFactory beanFactory; private transient final Map, InjectionMetadata> injectionMetadataCache = - new ConcurrentHashMap, InjectionMetadata>(); + new ConcurrentHashMap, InjectionMetadata>(64); private final Map extendedEntityManagersToClose = - new ConcurrentHashMap(); + new ConcurrentHashMap(16); /** diff --git a/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java b/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java index a52ba567598..2d23fd9cfa6 100644 --- a/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java +++ b/spring-test/src/main/java/org/springframework/mock/jndi/ExpectedLookupTemplate.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,27 +18,26 @@ package org.springframework.mock.jndi; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import javax.naming.NamingException; import org.springframework.jndi.JndiTemplate; /** - * Simple extension of the JndiTemplate class that always returns a given - * object. Very useful for testing. Effectively a mock object. - * + * Simple extension of the JndiTemplate class that always returns a given object. + * + *

Very useful for testing. Effectively a mock object. + * * @author Rod Johnson * @author Juergen Hoeller */ public class ExpectedLookupTemplate extends JndiTemplate { - private final Map jndiObjects = new ConcurrentHashMap(); + private final Map jndiObjects = new ConcurrentHashMap(16); /** * Construct a new JndiTemplate that will always return given objects for * given names. To be populated through addObject calls. - * * @see #addObject(String, Object) */ public ExpectedLookupTemplate() { @@ -47,7 +46,6 @@ public class ExpectedLookupTemplate extends JndiTemplate { /** * Construct a new JndiTemplate that will always return the given object, * but honour only requests for the given name. - * * @param name the name the client is expected to look up * @param object the object that will be returned */ @@ -56,9 +54,7 @@ public class ExpectedLookupTemplate extends JndiTemplate { } /** - * Add the given object to the list of JNDI objects that this template will - * expose. - * + * Add the given object to the list of JNDI objects that this template will expose. * @param name the name the client is expected to look up * @param object the object that will be returned */ diff --git a/spring-test/src/main/java/org/springframework/test/context/ContextCache.java b/spring-test/src/main/java/org/springframework/test/context/ContextCache.java index e449ab866ec..9185a796d30 100644 --- a/spring-test/src/main/java/org/springframework/test/context/ContextCache.java +++ b/spring-test/src/main/java/org/springframework/test/context/ContextCache.java @@ -44,7 +44,8 @@ class ContextCache { /** * Map of context keys to Spring ApplicationContext instances. */ - private final Map contextMap = new ConcurrentHashMap(); + private final Map contextMap = + new ConcurrentHashMap(64); private int hitCount; @@ -69,7 +70,6 @@ class ContextCache { /** * Return whether there is a cached context for the given key. - * * @param key the context key (never null) */ boolean contains(MergedContextConfiguration key) { @@ -79,10 +79,8 @@ class ContextCache { /** * Obtain a cached ApplicationContext for the given key. - * *

The {@link #getHitCount() hit} and {@link #getMissCount() miss} * counts will be updated accordingly. - * * @param key the context key (never null) * @return the corresponding ApplicationContext instance, * or null if not found in the cache. @@ -135,7 +133,6 @@ class ContextCache { /** * Explicitly add an ApplicationContext instance to the cache under the given key. - * * @param key the context key (never null) * @param context the ApplicationContext instance (never null) */ @@ -147,7 +144,6 @@ class ContextCache { /** * Remove the context with the given key. - * * @param key the context key (never null) * @return the corresponding ApplicationContext instance, or null * if not found in the cache. @@ -162,11 +158,9 @@ class ContextCache { * {@link #remove removing} the context from the cache and explicitly * {@link ConfigurableApplicationContext#close() closing} it if it is an * instance of {@link ConfigurableApplicationContext}. - * *

Generally speaking, you would only call this method if you change the * state of a singleton bean, potentially affecting future interaction with * the context. - * * @param key the context key (never null) * @see #remove */ @@ -192,11 +186,8 @@ class ContextCache { * as the {@link #hitCount hit} and {@link #missCount miss} counts. */ public String toString() { - return new ToStringCreator(this)// - .append("size", size())// - .append("hitCount", getHitCount())// - .append("missCount", getMissCount())// - .toString(); + return new ToStringCreator(this).append("size", size()).append("hitCount", getHitCount()). + append("missCount", getMissCount()).toString(); } } diff --git a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java index 40acf3b1697..0dab576fa21 100644 --- a/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java +++ b/spring-test/src/main/java/org/springframework/test/context/transaction/TransactionalTestExecutionListener.java @@ -21,12 +21,13 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; -import java.util.IdentityHashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryUtils; @@ -111,7 +112,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource(); private final Map transactionContextCache = - Collections.synchronizedMap(new IdentityHashMap()); + new ConcurrentHashMap(8); private TransactionConfigurationAttributes configurationAttributes; diff --git a/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java b/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java index 8ef4e5ef1fa..dd144cfcb2f 100644 --- a/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java +++ b/spring-tx/src/main/java/org/springframework/transaction/interceptor/AbstractFallbackTransactionAttributeSource.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -69,7 +69,7 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran *

As this base class is not marked Serializable, the cache will be recreated * after serialization - provided that the concrete subclass is Serializable. */ - final Map attributeCache = new ConcurrentHashMap(); + final Map attributeCache = new ConcurrentHashMap(1024); /** diff --git a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java index 68f67694dba..3a0bce583ab 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/xml/AbstractJaxb2HttpMessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,19 +27,19 @@ import org.springframework.http.converter.HttpMessageConversionException; import org.springframework.util.Assert; /** - * Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} that - * use JAXB2. Creates {@link JAXBContext} object lazily. + * Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} + * that use JAXB2. Creates {@link JAXBContext} object lazily. * * @author Arjen Poutsma * @since 3.0 */ public abstract class AbstractJaxb2HttpMessageConverter extends AbstractXmlHttpMessageConverter { - private final ConcurrentMap jaxbContexts = new ConcurrentHashMap(); + private final ConcurrentMap jaxbContexts = new ConcurrentHashMap(64); + /** - * Creates a new {@link Marshaller} for the given class. - * + * Create a new {@link Marshaller} for the given class. * @param clazz the class to create the marshaller for * @return the {@code Marshaller} * @throws HttpMessageConversionException in case of JAXB errors @@ -56,8 +56,7 @@ public abstract class AbstractJaxb2HttpMessageConverter extends AbstractXmlHt } /** - * Creates a new {@link Unmarshaller} for the given class. - * + * Create a new {@link Unmarshaller} for the given class. * @param clazz the class to create the unmarshaller for * @return the {@code Unmarshaller} * @throws HttpMessageConversionException in case of JAXB errors @@ -74,19 +73,18 @@ public abstract class AbstractJaxb2HttpMessageConverter extends AbstractXmlHt } /** - * Returns a {@link JAXBContext} for the given class. - * + * Return a {@link JAXBContext} for the given class. * @param clazz the class to return the context for * @return the {@code JAXBContext} * @throws HttpMessageConversionException in case of JAXB errors */ protected final JAXBContext getJaxbContext(Class clazz) { Assert.notNull(clazz, "'clazz' must not be null"); - JAXBContext jaxbContext = jaxbContexts.get(clazz); + JAXBContext jaxbContext = this.jaxbContexts.get(clazz); if (jaxbContext == null) { try { jaxbContext = JAXBContext.newInstance(clazz); - jaxbContexts.putIfAbsent(clazz, jaxbContext); + this.jaxbContexts.putIfAbsent(clazz, jaxbContext); } catch (JAXBException ex) { throw new HttpMessageConversionException( diff --git a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java index b694510158e..293f26ce7ad 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java +++ b/spring-web/src/main/java/org/springframework/web/accept/MappingMediaTypeFileExtensionResolver.java @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.web.accept; -import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; @@ -37,11 +38,12 @@ import org.springframework.util.MultiValueMap; */ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver { - private final ConcurrentMap mediaTypes = new ConcurrentHashMap(); + private final ConcurrentMap mediaTypes = new ConcurrentHashMap(64); private final MultiValueMap fileExtensions = new LinkedMultiValueMap(); - private final List allFileExtensions = new ArrayList(); + private final List allFileExtensions = new LinkedList(); + /** * Create an instance with the given mappings between extensions and media types. @@ -89,4 +91,4 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten } } -} \ No newline at end of file +} diff --git a/spring-web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java b/spring-web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java index 836e3b5095e..3595a888932 100644 --- a/spring-web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java +++ b/spring-web/src/main/java/org/springframework/web/bind/annotation/support/HandlerMethodResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,10 +19,11 @@ package org.springframework.web.bind.annotation.support; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; +import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.BridgeMethodResolver; import org.springframework.core.annotation.AnnotationUtils; @@ -64,7 +65,8 @@ public class HandlerMethodResolver { private final Set sessionAttributeTypes = new HashSet(); - private final Set actualSessionAttributeNames = Collections.synchronizedSet(new HashSet(4)); + // using a ConcurrentHashMap as a Set + private final Map actualSessionAttributeNames = new ConcurrentHashMap(4); /** @@ -152,7 +154,7 @@ public class HandlerMethodResolver { public boolean isSessionAttribute(String attrName, Class attrType) { if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) { - this.actualSessionAttributeNames.add(attrName); + this.actualSessionAttributeNames.put(attrName, Boolean.TRUE); return true; } else { @@ -161,7 +163,7 @@ public class HandlerMethodResolver { } public Set getActualSessionAttributeNames() { - return this.actualSessionAttributeNames; + return this.actualSessionAttributeNames.keySet(); } } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java index 63e318125ff..9e35288687c 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/AbstractNamedValueMethodArgumentResolver.java @@ -62,7 +62,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle private final BeanExpressionContext expressionContext; private Map namedValueInfoCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(256); /** * @param beanFactory a bean factory to use for resolving ${...} placeholder @@ -80,11 +80,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle throws Exception { Class paramType = parameter.getParameterType(); - NamedValueInfo namedValueInfo = getNamedValueInfo(parameter); Object arg = resolveName(namedValueInfo.name, parameter, webRequest); - if (arg == null) { if (namedValueInfo.defaultValue != null) { arg = resolveDefaultValue(namedValueInfo.defaultValue); @@ -121,7 +119,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle /** * Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically * retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}. - * * @param parameter the method parameter * @return the named value information */ @@ -146,7 +143,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle * @param name the name of the value being resolved * @param parameter the method parameter to resolve to an argument value * @param request the current request - * * @return the resolved argument. May be {@code null} * @throws Exception in case of errors */ @@ -203,9 +199,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle */ protected void handleResolvedValue(Object arg, String name, MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) { - } + /** * Represents the information about a named value, including name, whether it's required and a default value. */ @@ -223,4 +219,5 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle this.defaultValue = defaultValue; } } + } diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java b/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java index 22dd998229a..626b0fe2189 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/ExceptionHandlerMethodResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,10 +46,10 @@ public class ExceptionHandlerMethodResolver { private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis"); private final Map, Method> mappedMethods = - new ConcurrentHashMap, Method>(); + new ConcurrentHashMap, Method>(16); private final Map, Method> exceptionLookupCache = - new ConcurrentHashMap, Method>(); + new ConcurrentHashMap, Method>(16); /** * A constructor that finds {@link ExceptionHandler} methods in the given type. diff --git a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java index 5e6080db13e..bd14d2dc217 100644 --- a/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java +++ b/spring-web/src/main/java/org/springframework/web/method/annotation/SessionAttributesHandler.java @@ -17,11 +17,11 @@ package org.springframework.web.method.annotation; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; @@ -50,10 +50,12 @@ public class SessionAttributesHandler { private final Set> attributeTypes = new HashSet>(); - private final Set knownAttributeNames = Collections.synchronizedSet(new HashSet(4)); + // using a ConcurrentHashMap as a Set + private final Map knownAttributeNames = new ConcurrentHashMap(4); private final SessionAttributeStore sessionAttributeStore; + /** * Create a new instance for a controller type. Session attribute names and * types are extracted from the {@code @SessionAttributes} annotation, if @@ -71,7 +73,9 @@ public class SessionAttributesHandler { this.attributeTypes.addAll(Arrays.>asList(annotation.types())); } - this.knownAttributeNames.addAll(this.attributeNames); + for (String attributeName : this.attributeNames) { + this.knownAttributeNames.put(attributeName, Boolean.TRUE); + } } /** @@ -96,7 +100,7 @@ public class SessionAttributesHandler { public boolean isHandlerSessionAttribute(String attributeName, Class attributeType) { Assert.notNull(attributeName, "Attribute name must not be null"); if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) { - this.knownAttributeNames.add(attributeName); + this.knownAttributeNames.put(attributeName, Boolean.TRUE); return true; } else { @@ -130,7 +134,7 @@ public class SessionAttributesHandler { */ public Map retrieveAttributes(WebRequest request) { Map attributes = new HashMap(); - for (String name : this.knownAttributeNames) { + for (String name : this.knownAttributeNames.keySet()) { Object value = this.sessionAttributeStore.retrieveAttribute(request, name); if (value != null) { attributes.put(name, value); @@ -146,7 +150,7 @@ public class SessionAttributesHandler { * @param request the current request */ public void cleanupAttributes(WebRequest request) { - for (String attributeName : this.knownAttributeNames) { + for (String attributeName : this.knownAttributeNames.keySet()) { this.sessionAttributeStore.cleanupAttribute(request, attributeName); } } @@ -161,4 +165,4 @@ public class SessionAttributesHandler { return this.sessionAttributeStore.retrieveAttribute(request, attributeName); } -} \ No newline at end of file +} diff --git a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java index b01482d953f..21c88153fbd 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/HandlerMethodArgumentResolverComposite.java @@ -16,14 +16,15 @@ package org.springframework.web.method.support; -import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.MethodParameter; import org.springframework.util.Assert; import org.springframework.web.bind.support.WebDataBinderFactory; @@ -41,10 +42,11 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu protected final Log logger = LogFactory.getLog(getClass()); private final List argumentResolvers = - new ArrayList(); + new LinkedList(); private final Map argumentResolverCache = - new ConcurrentHashMap(); + new ConcurrentHashMap(256); + /** * Return a read-only list with the contained resolvers, or an empty list. @@ -81,7 +83,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter); if (result == null) { - for (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) { + for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) { if (logger.isTraceEnabled()) { logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" + parameter.getGenericParameterType() + "]"); diff --git a/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index abdd7a322a0..da4991220eb 100644 --- a/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -151,7 +151,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator private BeanExpressionContext expressionContext; private final Map, PortletHandlerMethodResolver> methodResolverCache = - new ConcurrentHashMap, PortletHandlerMethodResolver>(); + new ConcurrentHashMap, PortletHandlerMethodResolver>(64); /** diff --git a/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java b/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java index 35eb460a228..0f763828c37 100644 --- a/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java +++ b/spring-webmvc-portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -30,7 +30,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import javax.portlet.ClientDataRequest; import javax.portlet.Event; import javax.portlet.EventRequest; @@ -76,11 +75,14 @@ import org.springframework.web.servlet.View; public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver { // dummy method placeholder - private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class[]) null); + private static final Method NO_METHOD_FOUND = + ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class[]) null); + + private final Map, Map, Method>> exceptionHandlerCache = + new ConcurrentHashMap, Map, Method>>(64); private WebArgumentResolver[] customArgumentResolvers; - private final Map, Map, Method>> exceptionHandlerCache = new ConcurrentHashMap, Map, Method>>(); /** * Set a custom ArgumentResolvers to use for special method parameter types. @@ -134,18 +136,18 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) { final Class handlerType = handler.getClass(); final Class thrownExceptionType = thrownException.getClass(); - Method handlerMethod = null; - - Map, Method> handlers = exceptionHandlerCache.get(handlerType); + Method handlerMethod; + Map, Method> handlers = this.exceptionHandlerCache.get(handlerType); if (handlers != null) { handlerMethod = handlers.get(thrownExceptionType); if (handlerMethod != null) { return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod); } - } else { - handlers = new ConcurrentHashMap, Method>(); - exceptionHandlerCache.put(handlerType, handlers); + } + else { + handlers = new ConcurrentHashMap, Method>(16); + this.exceptionHandlerCache.put(handlerType, handlers); } final Map, Method> matchedHandlers = new HashMap, Method>(); @@ -205,7 +207,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc } /** - * Uses the {@link DepthComparator} to find the best matching method + * Uses the {@link ExceptionDepthComparator} to find the best matching method. * @return the best matching method or {@code null}. */ private Method getBestMatchingMethod( @@ -217,7 +219,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc Class closestMatch = ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException); Method method = resolverMethods.get(closestMatch); - return ((method == null) || (NO_METHOD_FOUND == method)) ? null : method; + return (method == null || NO_METHOD_FOUND == method ? null : method); } /** diff --git a/spring-webmvc-tiles3/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java b/spring-webmvc-tiles3/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java index 9f05299f1ba..746ffa40f01 100644 --- a/spring-webmvc-tiles3/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java +++ b/spring-webmvc-tiles3/src/main/java/org/springframework/web/servlet/view/tiles3/SimpleSpringPreparerFactory.java @@ -27,7 +27,7 @@ import org.springframework.web.context.WebApplicationContext; /** - * Tiles2 {@link org.apache.tiles.preparer.PreparerFactory} implementation + * Tiles3 {@link org.apache.tiles.preparer.PreparerFactory} implementation * that expects preparer class names and builds preparer instances for those, * creating them through the Spring ApplicationContext in order to apply * Spring container callbacks and configured Spring BeanPostProcessors. @@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext; */ public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory { - /** Cache of shared ViewPreparer instances: bean name --> bean instance */ - private final Map sharedPreparers = new ConcurrentHashMap(); + /** Cache of shared ViewPreparer instances: bean name -> bean instance */ + private final Map sharedPreparers = new ConcurrentHashMap(16); @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java index 8b692442b94..00d4f03035b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/UrlFilenameViewController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -54,7 +54,7 @@ public class UrlFilenameViewController extends AbstractUrlViewController { private String suffix = ""; /** Request URL path String --> view name String */ - private final Map viewNameCache = new ConcurrentHashMap(); + private final Map viewNameCache = new ConcurrentHashMap(256); /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index 34801814aae..29859d39b95 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -35,7 +35,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; - import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -46,6 +45,7 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; @@ -56,7 +56,6 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.Ordered; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.AnnotationUtils; -import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpInputMessage; @@ -188,9 +187,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator private BeanExpressionContext expressionContext; private final Map, ServletHandlerMethodResolver> methodResolverCache = - new ConcurrentHashMap, ServletHandlerMethodResolver>(); + new ConcurrentHashMap, ServletHandlerMethodResolver>(64); - private final Map, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap, Boolean>(); + private final Map, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap, Boolean>(64); public AnnotationMethodHandlerAdapter() { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java index 965b9055612..58b74010698 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerExceptionResolver.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; - import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -82,7 +81,7 @@ import org.springframework.web.servlet.support.RequestContextUtils; * @author Juergen Hoeller * @since 3.0 * - * @deprecated in Spring 3.2 in favor of + * @deprecated as of Spring 3.2, in favor of * {@link org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver} */ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver { @@ -91,7 +90,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class[]) null); private final Map, Map, Method>> exceptionHandlerCache = - new ConcurrentHashMap, Map, Method>>(); + new ConcurrentHashMap, Map, Method>>(64); private WebArgumentResolver[] customArgumentResolvers; @@ -162,8 +161,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc final Class thrownExceptionType = thrownException.getClass(); Method handlerMethod = null; - Map, Method> handlers = exceptionHandlerCache.get(handlerType); - + Map, Method> handlers = this.exceptionHandlerCache.get(handlerType); if (handlers != null) { handlerMethod = handlers.get(thrownExceptionType); if (handlerMethod != null) { @@ -171,8 +169,8 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc } } else { - handlers = new ConcurrentHashMap, Method>(); - exceptionHandlerCache.put(handlerType, handlers); + handlers = new ConcurrentHashMap, Method>(16); + this.exceptionHandlerCache.put(handlerType, handlers); } final Map, Method> matchedHandlers = new HashMap, Method>(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java index 9cad5e0d5b6..757d2744dd5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.java @@ -24,7 +24,6 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.xml.transform.Source; @@ -39,7 +38,6 @@ import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter; import org.springframework.http.converter.xml.SourceHttpMessageConverter; -import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter; import org.springframework.web.accept.ContentNegotiationManager; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.context.request.ServletWebRequest; @@ -82,7 +80,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); private final Map, ExceptionHandlerMethodResolver> exceptionHandlerCache = - new ConcurrentHashMap, ExceptionHandlerMethodResolver>(); + new ConcurrentHashMap, ExceptionHandlerMethodResolver>(64); private final Map exceptionHandlerAdviceCache = new LinkedHashMap(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java index 9c1e7617371..1b8da1a5eef 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java @@ -157,14 +157,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i private final Map, SessionAttributesHandler> sessionAttributesHandlerCache = - new ConcurrentHashMap, SessionAttributesHandler>(); + new ConcurrentHashMap, SessionAttributesHandler>(64); - private final Map, Set> initBinderCache = new ConcurrentHashMap, Set>(); + private final Map, Set> initBinderCache = new ConcurrentHashMap, Set>(64); private final Map> initBinderAdviceCache = new LinkedHashMap>(); - private final Map, Set> modelAttributeCache = new ConcurrentHashMap, Set>(); + private final Map, Set> modelAttributeCache = new ConcurrentHashMap, Set>(64); private final Map> modelAttributeAdviceCache = new LinkedHashMap>(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/multiaction/InternalPathMethodNameResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/multiaction/InternalPathMethodNameResolver.java index 875e132b67c..9b69f394661 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/multiaction/InternalPathMethodNameResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/multiaction/InternalPathMethodNameResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2008 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ public class InternalPathMethodNameResolver extends AbstractUrlMethodNameResolve private String suffix = ""; /** Request URL path String --> method name String */ - private final Map methodNameCache = new ConcurrentHashMap(); + private final Map methodNameCache = new ConcurrentHashMap(16); /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles2/SimpleSpringPreparerFactory.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles2/SimpleSpringPreparerFactory.java index 9fd33a38538..4dee4a8d8f6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles2/SimpleSpringPreparerFactory.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/tiles2/SimpleSpringPreparerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext; */ public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory { - /** Cache of shared ViewPreparer instances: bean name --> bean instance */ - private final Map sharedPreparers = new ConcurrentHashMap(); + /** Cache of shared ViewPreparer instances: bean name -> bean instance */ + private final Map sharedPreparers = new ConcurrentHashMap(16); @Override