Consistent fine-tuning of synchronized and concurrent data structures
In particular, avoiding synchronized Sets and Maps wherever possible (preferring a ConcurrentHashMap even instead of a synchronized Set) and specifying appropriate ConcurrentHashMap initial capacities (even if we end up choosing 16).
This commit is contained in:
parent
a2f8902b3a
commit
b9df7d68d9
|
@ -46,7 +46,7 @@ public abstract class AbstractAdvisingBeanPostProcessor extends ProxyConfig
|
||||||
*/
|
*/
|
||||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||||
|
|
||||||
private final Map<String, Boolean> eligibleBeans = new ConcurrentHashMap<String, Boolean>();
|
private final Map<String, Boolean> eligibleBeans = new ConcurrentHashMap<String, Boolean>(64);
|
||||||
|
|
||||||
|
|
||||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,11 +20,8 @@ import java.beans.PropertyDescriptor;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.aopalliance.aop.Advice;
|
import org.aopalliance.aop.Advice;
|
||||||
|
@ -136,15 +133,15 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||||
|
|
||||||
private BeanFactory beanFactory;
|
private BeanFactory beanFactory;
|
||||||
|
|
||||||
private final Set<Object> targetSourcedBeans = Collections.synchronizedSet(new HashSet<Object>());
|
private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<Object, Boolean>(64);
|
||||||
|
|
||||||
private final Set<Object> earlyProxyReferences = Collections.synchronizedSet(new HashSet<Object>());
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<String, Boolean> targetSourcedBeans = new ConcurrentHashMap<String, Boolean>(16);
|
||||||
|
|
||||||
private final Set<Object> advisedBeans = Collections.synchronizedSet(new HashSet<Object>());
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<Object, Boolean> earlyProxyReferences = new ConcurrentHashMap<Object, Boolean>(16);
|
||||||
|
|
||||||
private final Set<Object> nonAdvisedBeans = Collections.synchronizedSet(new HashSet<Object>());
|
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>(16);
|
||||||
|
|
||||||
private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<Object, Class<?>>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,19 +261,19 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||||
|
|
||||||
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
|
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
|
||||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||||
this.earlyProxyReferences.add(cacheKey);
|
this.earlyProxyReferences.put(cacheKey, Boolean.TRUE);
|
||||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
|
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
|
||||||
Object cacheKey = getCacheKey(beanClass, beanName);
|
Object cacheKey = getCacheKey(beanClass, beanName);
|
||||||
|
|
||||||
if (!this.targetSourcedBeans.contains(cacheKey)) {
|
if (!this.targetSourcedBeans.containsKey(beanName)) {
|
||||||
if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) {
|
if (this.advisedBeans.containsKey(cacheKey)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
|
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
|
||||||
this.nonAdvisedBeans.add(cacheKey);
|
this.advisedBeans.put(cacheKey, Boolean.FALSE);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +283,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||||
// The TargetSource will handle target instances in a custom fashion.
|
// The TargetSource will handle target instances in a custom fashion.
|
||||||
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
|
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
|
||||||
if (targetSource != null) {
|
if (targetSource != null) {
|
||||||
this.targetSourcedBeans.add(beanName);
|
this.targetSourcedBeans.put(beanName, Boolean.TRUE);
|
||||||
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
|
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
|
||||||
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
|
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
|
||||||
this.proxyTypes.put(cacheKey, proxy.getClass());
|
this.proxyTypes.put(cacheKey, proxy.getClass());
|
||||||
|
@ -318,7 +315,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||||
if (bean != null) {
|
if (bean != null) {
|
||||||
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
Object cacheKey = getCacheKey(bean.getClass(), beanName);
|
||||||
if (!this.earlyProxyReferences.contains(cacheKey)) {
|
if (!this.earlyProxyReferences.containsKey(cacheKey)) {
|
||||||
return wrapIfNecessary(bean, beanName, cacheKey);
|
return wrapIfNecessary(bean, beanName, cacheKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,27 +341,27 @@ public abstract class AbstractAutoProxyCreator extends ProxyConfig
|
||||||
* @return a proxy wrapping the bean, or the raw bean instance as-is
|
* @return a proxy wrapping the bean, or the raw bean instance as-is
|
||||||
*/
|
*/
|
||||||
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
|
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
|
||||||
if (this.targetSourcedBeans.contains(beanName)) {
|
if (this.targetSourcedBeans.containsKey(beanName)) {
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
if (this.nonAdvisedBeans.contains(cacheKey)) {
|
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
|
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
|
||||||
this.nonAdvisedBeans.add(cacheKey);
|
this.advisedBeans.put(cacheKey, Boolean.FALSE);
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create proxy if we have advice.
|
// Create proxy if we have advice.
|
||||||
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
|
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
|
||||||
if (specificInterceptors != DO_NOT_PROXY) {
|
if (specificInterceptors != DO_NOT_PROXY) {
|
||||||
this.advisedBeans.add(cacheKey);
|
this.advisedBeans.put(cacheKey, Boolean.TRUE);
|
||||||
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
|
Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
|
||||||
this.proxyTypes.put(cacheKey, proxy.getClass());
|
this.proxyTypes.put(cacheKey, proxy.getClass());
|
||||||
return proxy;
|
return proxy;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nonAdvisedBeans.add(cacheKey);
|
this.advisedBeans.put(cacheKey, Boolean.FALSE);
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
package org.springframework.aop.target;
|
package org.springframework.aop.target;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -62,7 +61,7 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
|
||||||
/**
|
/**
|
||||||
* Set of managed targets, enabling us to keep track of the targets we've created.
|
* Set of managed targets, enabling us to keep track of the targets we've created.
|
||||||
*/
|
*/
|
||||||
private final Set<Object> targetSet = Collections.synchronizedSet(new HashSet<Object>());
|
private final Set<Object> targetSet = new HashSet<Object>();
|
||||||
|
|
||||||
private int invocationCount;
|
private int invocationCount;
|
||||||
|
|
||||||
|
@ -85,7 +84,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
|
||||||
// Associate target with ThreadLocal.
|
// Associate target with ThreadLocal.
|
||||||
target = newPrototypeInstance();
|
target = newPrototypeInstance();
|
||||||
this.targetInThread.set(target);
|
this.targetInThread.set(target);
|
||||||
this.targetSet.add(target);
|
synchronized (this.targetSet) {
|
||||||
|
this.targetSet.add(target);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++this.hitCount;
|
++this.hitCount;
|
||||||
|
@ -119,7 +120,9 @@ public class ThreadLocalTargetSource extends AbstractPrototypeBasedTargetSource
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getObjectCount() {
|
public int getObjectCount() {
|
||||||
return this.targetSet.size();
|
synchronized (this.targetSet) {
|
||||||
|
return this.targetSet.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -57,6 +57,7 @@ public abstract class BeanUtils {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(BeanUtils.class);
|
private static final Log logger = LogFactory.getLog(BeanUtils.class);
|
||||||
|
|
||||||
|
// using WeakHashMap as a Set
|
||||||
private static final Map<Class<?>, Boolean> unknownEditorTypes =
|
private static final Map<Class<?>, Boolean> unknownEditorTypes =
|
||||||
Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>());
|
Collections.synchronizedMap(new WeakHashMap<Class<?>, Boolean>());
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,6 @@ import java.beans.Introspector;
|
||||||
import java.beans.PropertyDescriptor;
|
import java.beans.PropertyDescriptor;
|
||||||
import java.lang.ref.Reference;
|
import java.lang.ref.Reference;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -70,14 +69,14 @@ public class CachedIntrospectionResults {
|
||||||
* Set of ClassLoaders that this CachedIntrospectionResults class will always
|
* Set of ClassLoaders that this CachedIntrospectionResults class will always
|
||||||
* accept classes from, even if the classes do not qualify as cache-safe.
|
* accept classes from, even if the classes do not qualify as cache-safe.
|
||||||
*/
|
*/
|
||||||
static final Set<ClassLoader> acceptedClassLoaders = Collections.synchronizedSet(new HashSet<ClassLoader>());
|
static final Set<ClassLoader> acceptedClassLoaders = new HashSet<ClassLoader>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map keyed by class containing CachedIntrospectionResults.
|
* Map keyed by class containing CachedIntrospectionResults.
|
||||||
* Needs to be a WeakHashMap with WeakReferences as values to allow
|
* Needs to be a WeakHashMap with WeakReferences as values to allow
|
||||||
* for proper garbage collection in case of multiple class loaders.
|
* for proper garbage collection in case of multiple class loaders.
|
||||||
*/
|
*/
|
||||||
static final Map<Class, Object> classCache = Collections.synchronizedMap(new WeakHashMap<Class, Object>());
|
static final Map<Class, Object> classCache = new WeakHashMap<Class, Object>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +93,9 @@ public class CachedIntrospectionResults {
|
||||||
*/
|
*/
|
||||||
public static void acceptClassLoader(ClassLoader classLoader) {
|
public static void acceptClassLoader(ClassLoader classLoader) {
|
||||||
if (classLoader != null) {
|
if (classLoader != null) {
|
||||||
acceptedClassLoaders.add(classLoader);
|
synchronized (acceptedClassLoaders) {
|
||||||
|
acceptedClassLoaders.add(classLoader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +138,10 @@ public class CachedIntrospectionResults {
|
||||||
*/
|
*/
|
||||||
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
|
static CachedIntrospectionResults forClass(Class beanClass) throws BeansException {
|
||||||
CachedIntrospectionResults results;
|
CachedIntrospectionResults results;
|
||||||
Object value = classCache.get(beanClass);
|
Object value;
|
||||||
|
synchronized (classCache) {
|
||||||
|
value = classCache.get(beanClass);
|
||||||
|
}
|
||||||
if (value instanceof Reference) {
|
if (value instanceof Reference) {
|
||||||
Reference ref = (Reference) value;
|
Reference ref = (Reference) value;
|
||||||
results = (CachedIntrospectionResults) ref.get();
|
results = (CachedIntrospectionResults) ref.get();
|
||||||
|
@ -149,14 +153,18 @@ public class CachedIntrospectionResults {
|
||||||
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
if (ClassUtils.isCacheSafe(beanClass, CachedIntrospectionResults.class.getClassLoader()) ||
|
||||||
isClassLoaderAccepted(beanClass.getClassLoader())) {
|
isClassLoaderAccepted(beanClass.getClassLoader())) {
|
||||||
results = new CachedIntrospectionResults(beanClass);
|
results = new CachedIntrospectionResults(beanClass);
|
||||||
classCache.put(beanClass, results);
|
synchronized (classCache) {
|
||||||
|
classCache.put(beanClass, results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
logger.debug("Not strongly caching class [" + beanClass.getName() + "] because it is not cache-safe");
|
||||||
}
|
}
|
||||||
results = new CachedIntrospectionResults(beanClass);
|
results = new CachedIntrospectionResults(beanClass);
|
||||||
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
synchronized (classCache) {
|
||||||
|
classCache.put(beanClass, new WeakReference<CachedIntrospectionResults>(results));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
|
@ -172,8 +180,10 @@ public class CachedIntrospectionResults {
|
||||||
private static boolean isClassLoaderAccepted(ClassLoader classLoader) {
|
private static boolean isClassLoaderAccepted(ClassLoader classLoader) {
|
||||||
// Iterate over array copy in order to avoid synchronization for the entire
|
// Iterate over array copy in order to avoid synchronization for the entire
|
||||||
// ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator).
|
// ClassLoader check (avoiding a synchronized acceptedClassLoaders Iterator).
|
||||||
ClassLoader[] acceptedLoaderArray =
|
ClassLoader[] acceptedLoaderArray;
|
||||||
acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
|
synchronized (acceptedClassLoaders) {
|
||||||
|
acceptedLoaderArray = acceptedClassLoaders.toArray(new ClassLoader[acceptedClassLoaders.size()]);
|
||||||
|
}
|
||||||
for (ClassLoader registeredLoader : acceptedLoaderArray) {
|
for (ClassLoader registeredLoader : acceptedLoaderArray) {
|
||||||
if (isUnderneathClassLoader(classLoader, registeredLoader)) {
|
if (isUnderneathClassLoader(classLoader, registeredLoader)) {
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -119,10 +119,10 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
|
||||||
private ConfigurableListableBeanFactory beanFactory;
|
private ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
|
private final Map<Class<?>, Constructor<?>[]> candidateConstructorsCache =
|
||||||
new ConcurrentHashMap<Class<?>, Constructor<?>[]>();
|
new ConcurrentHashMap<Class<?>, Constructor<?>[]>(64);
|
||||||
|
|
||||||
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
private final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
|
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,8 +24,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -85,7 +83,7 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||||
private int order = Ordered.LOWEST_PRECEDENCE;
|
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||||
|
|
||||||
private transient final Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache =
|
private transient final Map<Class<?>, LifecycleMetadata> lifecycleMetadataCache =
|
||||||
new ConcurrentHashMap<Class<?>, LifecycleMetadata>();
|
new ConcurrentHashMap<Class<?>, LifecycleMetadata>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -240,69 +238,57 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||||
*/
|
*/
|
||||||
private class LifecycleMetadata {
|
private class LifecycleMetadata {
|
||||||
|
|
||||||
private final Set<LifecycleElement> initMethods;
|
private final Class targetClass;
|
||||||
|
|
||||||
private final Set<LifecycleElement> destroyMethods;
|
private final Collection<LifecycleElement> initMethods;
|
||||||
|
|
||||||
|
private final Collection<LifecycleElement> destroyMethods;
|
||||||
|
|
||||||
|
private volatile Set<LifecycleElement> checkedInitMethods;
|
||||||
|
|
||||||
|
private volatile Set<LifecycleElement> checkedDestroyMethods;
|
||||||
|
|
||||||
public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods,
|
public LifecycleMetadata(Class<?> targetClass, Collection<LifecycleElement> initMethods,
|
||||||
Collection<LifecycleElement> destroyMethods) {
|
Collection<LifecycleElement> destroyMethods) {
|
||||||
|
|
||||||
if (!initMethods.isEmpty()) {
|
this.targetClass = targetClass;
|
||||||
this.initMethods = Collections.synchronizedSet(new LinkedHashSet<LifecycleElement>(initMethods.size()));
|
this.initMethods = initMethods;
|
||||||
for (LifecycleElement element : initMethods) {
|
this.destroyMethods = destroyMethods;
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Found init method on class [" + targetClass.getName() + "]: " + element);
|
|
||||||
}
|
|
||||||
this.initMethods.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.initMethods = Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!destroyMethods.isEmpty()) {
|
|
||||||
this.destroyMethods = Collections.synchronizedSet(new LinkedHashSet<LifecycleElement>(destroyMethods.size()));
|
|
||||||
for (LifecycleElement element : destroyMethods) {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Found destroy method on class [" + targetClass.getName() + "]: " + element);
|
|
||||||
}
|
|
||||||
this.destroyMethods.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.destroyMethods = Collections.emptySet();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||||
synchronized(this.initMethods) {
|
Set<LifecycleElement> checkedInitMethods = new LinkedHashSet<LifecycleElement>(this.initMethods.size());
|
||||||
for (Iterator<LifecycleElement> it = this.initMethods.iterator(); it.hasNext();) {
|
for (LifecycleElement element : this.initMethods) {
|
||||||
String methodIdentifier = it.next().getIdentifier();
|
String methodIdentifier = element.getIdentifier();
|
||||||
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
|
if (!beanDefinition.isExternallyManagedInitMethod(methodIdentifier)) {
|
||||||
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
beanDefinition.registerExternallyManagedInitMethod(methodIdentifier);
|
||||||
}
|
checkedInitMethods.add(element);
|
||||||
else {
|
if (logger.isDebugEnabled()) {
|
||||||
it.remove();
|
logger.debug("Registered init method on class [" + this.targetClass.getName() + "]: " + element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
synchronized(this.destroyMethods) {
|
Set<LifecycleElement> checkedDestroyMethods = new LinkedHashSet<LifecycleElement>(this.destroyMethods.size());
|
||||||
for (Iterator<LifecycleElement> it = this.destroyMethods.iterator(); it.hasNext();) {
|
for (LifecycleElement element : this.destroyMethods) {
|
||||||
String methodIdentifier = it.next().getIdentifier();
|
String methodIdentifier = element.getIdentifier();
|
||||||
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
|
if (!beanDefinition.isExternallyManagedDestroyMethod(methodIdentifier)) {
|
||||||
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
beanDefinition.registerExternallyManagedDestroyMethod(methodIdentifier);
|
||||||
}
|
checkedDestroyMethods.add(element);
|
||||||
else {
|
if (logger.isDebugEnabled()) {
|
||||||
it.remove();
|
logger.debug("Registered destroy method on class [" + this.targetClass.getName() + "]: " + element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.checkedInitMethods = checkedInitMethods;
|
||||||
|
this.checkedDestroyMethods = checkedDestroyMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeInitMethods(Object target, String beanName) throws Throwable {
|
public void invokeInitMethods(Object target, String beanName) throws Throwable {
|
||||||
if (!this.initMethods.isEmpty()) {
|
Collection<LifecycleElement> initMethodsToIterate =
|
||||||
|
(this.checkedInitMethods != null ? this.checkedInitMethods : this.initMethods);
|
||||||
|
if (!initMethodsToIterate.isEmpty()) {
|
||||||
boolean debug = logger.isDebugEnabled();
|
boolean debug = logger.isDebugEnabled();
|
||||||
for (LifecycleElement element : this.initMethods) {
|
for (LifecycleElement element : initMethodsToIterate) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());
|
logger.debug("Invoking init method on bean '" + beanName + "': " + element.getMethod());
|
||||||
}
|
}
|
||||||
|
@ -312,9 +298,11 @@ public class InitDestroyAnnotationBeanPostProcessor
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
|
public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
|
||||||
if (!this.destroyMethods.isEmpty()) {
|
Collection<LifecycleElement> destroyMethodsToIterate =
|
||||||
|
(this.checkedDestroyMethods != null ? this.checkedDestroyMethods : this.destroyMethods);
|
||||||
|
if (!destroyMethodsToIterate.isEmpty()) {
|
||||||
boolean debug = logger.isDebugEnabled();
|
boolean debug = logger.isDebugEnabled();
|
||||||
for (LifecycleElement element : this.destroyMethods) {
|
for (LifecycleElement element : destroyMethodsToIterate) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
|
logger.debug("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
@ -50,42 +48,39 @@ public class InjectionMetadata {
|
||||||
|
|
||||||
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
private final Log logger = LogFactory.getLog(InjectionMetadata.class);
|
||||||
|
|
||||||
private final Set<InjectedElement> injectedElements;
|
private final Class targetClass;
|
||||||
|
|
||||||
|
private final Collection<InjectedElement> injectedElements;
|
||||||
|
|
||||||
|
private volatile Set<InjectedElement> checkedElements;
|
||||||
|
|
||||||
|
|
||||||
public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
|
public InjectionMetadata(Class targetClass, Collection<InjectedElement> elements) {
|
||||||
if (!elements.isEmpty()) {
|
this.targetClass = targetClass;
|
||||||
this.injectedElements = Collections.synchronizedSet(new LinkedHashSet<InjectedElement>(elements.size()));
|
this.injectedElements = elements;
|
||||||
for (InjectedElement element : elements) {
|
|
||||||
if (logger.isDebugEnabled()) {
|
|
||||||
logger.debug("Found injected element on class [" + targetClass.getName() + "]: " + element);
|
|
||||||
}
|
|
||||||
this.injectedElements.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.injectedElements = Collections.emptySet();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
|
||||||
synchronized (this.injectedElements) {
|
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
|
||||||
for (Iterator<InjectedElement> it = this.injectedElements.iterator(); it.hasNext();) {
|
for (InjectedElement element : this.injectedElements) {
|
||||||
Member member = it.next().getMember();
|
Member member = element.getMember();
|
||||||
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
|
||||||
beanDefinition.registerExternallyManagedConfigMember(member);
|
beanDefinition.registerExternallyManagedConfigMember(member);
|
||||||
}
|
checkedElements.add(element);
|
||||||
else {
|
if (logger.isDebugEnabled()) {
|
||||||
it.remove();
|
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.checkedElements = checkedElements;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
|
||||||
if (!this.injectedElements.isEmpty()) {
|
Collection<InjectedElement> elementsToIterate =
|
||||||
|
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
|
||||||
|
if (!elementsToIterate.isEmpty()) {
|
||||||
boolean debug = logger.isDebugEnabled();
|
boolean debug = logger.isDebugEnabled();
|
||||||
for (InjectedElement element : this.injectedElements) {
|
for (InjectedElement element : elementsToIterate) {
|
||||||
if (debug) {
|
if (debug) {
|
||||||
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
logger.debug("Processing injected method of bean '" + beanName + "': " + element);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,10 +20,9 @@ import java.beans.PropertyDescriptor;
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.PropertyValues;
|
import org.springframework.beans.PropertyValues;
|
||||||
|
@ -89,8 +88,11 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||||
|
|
||||||
private ConfigurableListableBeanFactory beanFactory;
|
private ConfigurableListableBeanFactory beanFactory;
|
||||||
|
|
||||||
/** Cache for validated bean names, skipping re-validation for the same bean */
|
/**
|
||||||
private final Set<String> validatedBeanNames = Collections.synchronizedSet(new HashSet<String>());
|
* Cache for validated bean names, skipping re-validation for the same bean
|
||||||
|
* (using a ConcurrentHashMap as a Set)
|
||||||
|
*/
|
||||||
|
private final Map<String, Boolean> validatedBeanNames = new ConcurrentHashMap<String, Boolean>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -137,7 +139,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||||
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
|
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
|
|
||||||
if (!this.validatedBeanNames.contains(beanName)) {
|
if (!this.validatedBeanNames.containsKey(beanName)) {
|
||||||
if (!shouldSkip(this.beanFactory, beanName)) {
|
if (!shouldSkip(this.beanFactory, beanName)) {
|
||||||
List<String> invalidProperties = new ArrayList<String>();
|
List<String> invalidProperties = new ArrayList<String>();
|
||||||
for (PropertyDescriptor pd : pds) {
|
for (PropertyDescriptor pd : pds) {
|
||||||
|
@ -149,7 +151,7 @@ public class RequiredAnnotationBeanPostProcessor extends InstantiationAwareBeanP
|
||||||
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
|
throw new BeanInitializationException(buildExceptionMessage(invalidProperties, beanName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.validatedBeanNames.add(beanName);
|
this.validatedBeanNames.put(beanName, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
return pvs;
|
return pvs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,11 +16,10 @@
|
||||||
|
|
||||||
package org.springframework.beans.factory.config;
|
package org.springframework.beans.factory.config;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashSet;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.PropertyValue;
|
import org.springframework.beans.PropertyValue;
|
||||||
|
@ -71,8 +70,11 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||||
|
|
||||||
private boolean ignoreInvalidKeys = false;
|
private boolean ignoreInvalidKeys = false;
|
||||||
|
|
||||||
/** Contains names of beans that have overrides */
|
/**
|
||||||
private Set<String> beanNames = Collections.synchronizedSet(new HashSet<String>());
|
* Contains names of beans that have overrides
|
||||||
|
* (using a ConcurrentHashMap as a Set)
|
||||||
|
*/
|
||||||
|
private Map<String, Boolean> beanNames = new ConcurrentHashMap<String, Boolean>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +130,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||||
}
|
}
|
||||||
String beanName = key.substring(0, separatorIndex);
|
String beanName = key.substring(0, separatorIndex);
|
||||||
String beanProperty = key.substring(separatorIndex+1);
|
String beanProperty = key.substring(separatorIndex+1);
|
||||||
this.beanNames.add(beanName);
|
this.beanNames.put(beanName, Boolean.TRUE);
|
||||||
applyPropertyValue(factory, beanName, beanProperty, value);
|
applyPropertyValue(factory, beanName, beanProperty, value);
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Property '" + key + "' set to value [" + value + "]");
|
logger.debug("Property '" + key + "' set to value [" + value + "]");
|
||||||
|
@ -159,7 +161,7 @@ public class PropertyOverrideConfigurer extends PropertyResourceConfigurer {
|
||||||
* the named bean
|
* the named bean
|
||||||
*/
|
*/
|
||||||
public boolean hasPropertyOverridesFor(String beanName) {
|
public boolean hasPropertyOverridesFor(String beanName) {
|
||||||
return this.beanNames.contains(beanName);
|
return this.beanNames.containsKey(beanName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,11 +145,11 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
|
||||||
|
|
||||||
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
|
/** Cache of unfinished FactoryBean instances: FactoryBean name --> BeanWrapper */
|
||||||
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
|
private final Map<String, BeanWrapper> factoryBeanInstanceCache =
|
||||||
new ConcurrentHashMap<String, BeanWrapper>();
|
new ConcurrentHashMap<String, BeanWrapper>(16);
|
||||||
|
|
||||||
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
|
/** Cache of filtered PropertyDescriptors: bean Class -> PropertyDescriptor array */
|
||||||
private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
|
private final Map<Class, PropertyDescriptor[]> filteredPropertyDescriptorsCache =
|
||||||
new ConcurrentHashMap<Class, PropertyDescriptor[]>();
|
new ConcurrentHashMap<Class, PropertyDescriptor[]>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.security.PrivilegedActionException;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
@ -151,17 +150,20 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||||
private boolean hasDestructionAwareBeanPostProcessors;
|
private boolean hasDestructionAwareBeanPostProcessors;
|
||||||
|
|
||||||
/** Map from scope identifier String to corresponding Scope */
|
/** Map from scope identifier String to corresponding Scope */
|
||||||
private final Map<String, Scope> scopes = new HashMap<String, Scope>();
|
private final Map<String, Scope> scopes = new HashMap<String, Scope>(8);
|
||||||
|
|
||||||
/** Security context used when running with a SecurityManager */
|
/** Security context used when running with a SecurityManager */
|
||||||
private SecurityContextProvider securityContextProvider;
|
private SecurityContextProvider securityContextProvider;
|
||||||
|
|
||||||
/** Map from bean name to merged RootBeanDefinition */
|
/** Map from bean name to merged RootBeanDefinition */
|
||||||
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
|
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
|
||||||
new ConcurrentHashMap<String, RootBeanDefinition>();
|
new ConcurrentHashMap<String, RootBeanDefinition>(64);
|
||||||
|
|
||||||
/** Names of beans that have already been created at least once */
|
/**
|
||||||
private final Set<String> alreadyCreated = Collections.synchronizedSet(new HashSet<String>());
|
* Names of beans that have already been created at least once
|
||||||
|
* (using a ConcurrentHashMap as a Set)
|
||||||
|
*/
|
||||||
|
private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);
|
||||||
|
|
||||||
/** Names of beans that are currently in creation */
|
/** Names of beans that are currently in creation */
|
||||||
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
|
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
|
||||||
|
@ -1372,7 +1374,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||||
* @param beanName the name of the bean
|
* @param beanName the name of the bean
|
||||||
*/
|
*/
|
||||||
protected void markBeanAsCreated(String beanName) {
|
protected void markBeanAsCreated(String beanName) {
|
||||||
this.alreadyCreated.add(beanName);
|
this.alreadyCreated.put(beanName, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1383,7 +1385,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||||
* at this point already
|
* at this point already
|
||||||
*/
|
*/
|
||||||
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
|
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
|
||||||
return this.alreadyCreated.contains(beanName);
|
return this.alreadyCreated.containsKey(beanName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1393,7 +1395,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||||
* @return <code>true</code> if actually removed, <code>false</code> otherwise
|
* @return <code>true</code> if actually removed, <code>false</code> otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
|
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
|
||||||
if (!this.alreadyCreated.contains(beanName)) {
|
if (!this.alreadyCreated.containsKey(beanName)) {
|
||||||
removeSingleton(beanName);
|
removeSingleton(beanName);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
|
|
||||||
/** Map from serialized id to factory instance */
|
/** Map from serialized id to factory instance */
|
||||||
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
|
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
|
||||||
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>();
|
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
|
||||||
|
|
||||||
/** Optional id for this factory, for serialization purposes */
|
/** Optional id for this factory, for serialization purposes */
|
||||||
private String serializationId;
|
private String serializationId;
|
||||||
|
@ -127,16 +127,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
|
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
|
||||||
|
|
||||||
/** Map from dependency type to corresponding autowired value */
|
/** Map from dependency type to corresponding autowired value */
|
||||||
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>();
|
private final Map<Class<?>, Object> resolvableDependencies = new HashMap<Class<?>, Object>(16);
|
||||||
|
|
||||||
/** Map of bean definition objects, keyed by bean name */
|
/** Map of bean definition objects, keyed by bean name */
|
||||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
|
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
|
||||||
|
|
||||||
/** Map of singleton bean names keyed by bean class */
|
/** Map of singleton bean names keyed by bean class */
|
||||||
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>();
|
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||||
|
|
||||||
/** Map of non-singleton bean names keyed by bean class */
|
/** Map of non-singleton bean names keyed by bean class */
|
||||||
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>();
|
private final Map<Class<?>, String[]> nonSingletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
|
||||||
|
|
||||||
/** List of bean definition names, in registration order */
|
/** List of bean definition names, in registration order */
|
||||||
private final List<String> beanDefinitionNames = new ArrayList<String>();
|
private final List<String> beanDefinitionNames = new ArrayList<String>();
|
||||||
|
|
|
@ -81,22 +81,22 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
/** Cache of singleton objects: bean name --> bean instance */
|
/** Cache of singleton objects: bean name --> bean instance */
|
||||||
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
|
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
|
||||||
|
|
||||||
/** Cache of singleton factories: bean name --> ObjectFactory */
|
/** Cache of singleton factories: bean name --> ObjectFactory */
|
||||||
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>();
|
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
|
||||||
|
|
||||||
/** Cache of early singleton objects: bean name --> bean instance */
|
/** Cache of early singleton objects: bean name --> bean instance */
|
||||||
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>();
|
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
|
||||||
|
|
||||||
/** Set of registered singletons, containing the bean names in registration order */
|
/** Set of registered singletons, containing the bean names in registration order */
|
||||||
private final Set<String> registeredSingletons = new LinkedHashSet<String>(16);
|
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
|
||||||
|
|
||||||
/** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */
|
/** Names of beans that are currently in creation (using a ConcurrentHashMap as a Set) */
|
||||||
private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>();
|
private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);
|
||||||
|
|
||||||
/** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */
|
/** Names of beans currently excluded from in creation checks (using a ConcurrentHashMap as a Set) */
|
||||||
private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>();
|
private final Map<String, Boolean> inCreationCheckExclusions = new ConcurrentHashMap<String, Boolean>(16);
|
||||||
|
|
||||||
/** List of suppressed Exceptions, available for associating related causes */
|
/** List of suppressed Exceptions, available for associating related causes */
|
||||||
private Set<Exception> suppressedExceptions;
|
private Set<Exception> suppressedExceptions;
|
||||||
|
@ -108,13 +108,13 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
|
||||||
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
|
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
|
/** Map between containing bean names: bean name --> Set of bean names that the bean contains */
|
||||||
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16);
|
||||||
|
|
||||||
/** Map between dependent bean names: bean name --> Set of dependent bean names */
|
/** Map between dependent bean names: bean name --> Set of dependent bean names */
|
||||||
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
|
||||||
|
|
||||||
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
|
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
|
||||||
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>();
|
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);
|
||||||
|
|
||||||
|
|
||||||
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
|
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -43,7 +43,7 @@ import org.springframework.beans.factory.FactoryBeanNotInitializedException;
|
||||||
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
|
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
|
||||||
|
|
||||||
/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */
|
/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */
|
||||||
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>();
|
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -18,9 +18,8 @@ package org.springframework.beans.factory.support;
|
||||||
|
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Map;
|
||||||
import java.util.HashSet;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.beans.MutablePropertyValues;
|
import org.springframework.beans.MutablePropertyValues;
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
@ -48,11 +47,14 @@ import org.springframework.util.Assert;
|
||||||
*/
|
*/
|
||||||
public class RootBeanDefinition extends AbstractBeanDefinition {
|
public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
|
|
||||||
private final Set<Member> externallyManagedConfigMembers = Collections.synchronizedSet(new HashSet<Member>(0));
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<Member, Boolean> externallyManagedConfigMembers = new ConcurrentHashMap<Member, Boolean>(0);
|
||||||
|
|
||||||
private final Set<String> externallyManagedInitMethods = Collections.synchronizedSet(new HashSet<String>(0));
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<String, Boolean> externallyManagedInitMethods = new ConcurrentHashMap<String, Boolean>(0);
|
||||||
|
|
||||||
private final Set<String> externallyManagedDestroyMethods = Collections.synchronizedSet(new HashSet<String>(0));
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<String, Boolean> externallyManagedDestroyMethods = new ConcurrentHashMap<String, Boolean>(0);
|
||||||
|
|
||||||
private BeanDefinitionHolder decoratedDefinition;
|
private BeanDefinitionHolder decoratedDefinition;
|
||||||
|
|
||||||
|
@ -277,27 +279,27 @@ public class RootBeanDefinition extends AbstractBeanDefinition {
|
||||||
|
|
||||||
|
|
||||||
public void registerExternallyManagedConfigMember(Member configMember) {
|
public void registerExternallyManagedConfigMember(Member configMember) {
|
||||||
this.externallyManagedConfigMembers.add(configMember);
|
this.externallyManagedConfigMembers.put(configMember, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedConfigMember(Member configMember) {
|
public boolean isExternallyManagedConfigMember(Member configMember) {
|
||||||
return this.externallyManagedConfigMembers.contains(configMember);
|
return this.externallyManagedConfigMembers.containsKey(configMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerExternallyManagedInitMethod(String initMethod) {
|
public void registerExternallyManagedInitMethod(String initMethod) {
|
||||||
this.externallyManagedInitMethods.add(initMethod);
|
this.externallyManagedInitMethods.put(initMethod, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedInitMethod(String initMethod) {
|
public boolean isExternallyManagedInitMethod(String initMethod) {
|
||||||
return this.externallyManagedInitMethods.contains(initMethod);
|
return this.externallyManagedInitMethods.containsKey(initMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
public void registerExternallyManagedDestroyMethod(String destroyMethod) {
|
||||||
this.externallyManagedDestroyMethods.add(destroyMethod);
|
this.externallyManagedDestroyMethods.put(destroyMethod, Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
public boolean isExternallyManagedDestroyMethod(String destroyMethod) {
|
||||||
return this.externallyManagedDestroyMethods.contains(destroyMethod);
|
return this.externallyManagedDestroyMethods.containsKey(destroyMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
|
public void setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -37,7 +37,7 @@ import org.springframework.util.StringUtils;
|
||||||
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
|
public class SimpleBeanDefinitionRegistry extends SimpleAliasRegistry implements BeanDefinitionRegistry {
|
||||||
|
|
||||||
/** Map of bean definition objects, keyed by bean name */
|
/** Map of bean definition objects, keyed by bean name */
|
||||||
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
|
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
|
||||||
|
|
||||||
|
|
||||||
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
|
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -155,7 +155,7 @@ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Loaded NamespaceHandler mappings: " + mappings);
|
logger.debug("Loaded NamespaceHandler mappings: " + mappings);
|
||||||
}
|
}
|
||||||
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>();
|
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
|
||||||
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
|
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
|
||||||
this.handlerMappings = handlerMappings;
|
this.handlerMappings = handlerMappings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -145,7 +145,7 @@ public class PluggableSchemaResolver implements EntityResolver {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Loaded schema mappings: " + mappings);
|
logger.debug("Loaded schema mappings: " + mappings);
|
||||||
}
|
}
|
||||||
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>();
|
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
|
||||||
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
|
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
|
||||||
this.schemaMappings = schemaMappings;
|
this.schemaMappings = schemaMappings;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ public class ConcurrentMapCache implements Cache {
|
||||||
* @param name the name of the cache
|
* @param name the name of the cache
|
||||||
*/
|
*/
|
||||||
public ConcurrentMapCache(String name) {
|
public ConcurrentMapCache(String name) {
|
||||||
this(name, new ConcurrentHashMap<Object, Object>(), true);
|
this(name, new ConcurrentHashMap<Object, Object>(256), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,7 @@ public class ConcurrentMapCache implements Cache {
|
||||||
* @param allowNullValues whether to accept and convert null values for this cache
|
* @param allowNullValues whether to accept and convert null values for this cache
|
||||||
*/
|
*/
|
||||||
public ConcurrentMapCache(String name, boolean allowNullValues) {
|
public ConcurrentMapCache(String name, boolean allowNullValues) {
|
||||||
this(name, new ConcurrentHashMap<Object, Object>(), allowNullValues);
|
this(name, new ConcurrentHashMap<Object, Object>(256), allowNullValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -36,7 +36,7 @@ import org.springframework.cache.CacheManager;
|
||||||
*/
|
*/
|
||||||
public class ConcurrentMapCacheManager implements CacheManager {
|
public class ConcurrentMapCacheManager implements CacheManager {
|
||||||
|
|
||||||
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
|
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
|
||||||
|
|
||||||
private boolean dynamic = true;
|
private boolean dynamic = true;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -25,6 +25,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.core.BridgeMethodResolver;
|
import org.springframework.core.BridgeMethodResolver;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
@ -48,6 +49,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
* configurable.
|
* configurable.
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
|
public abstract class AbstractFallbackCacheOperationSource implements CacheOperationSource {
|
||||||
|
@ -70,7 +72,8 @@ public abstract class AbstractFallbackCacheOperationSource implements CacheOpera
|
||||||
* <p>As this base class is not marked Serializable, the cache will be recreated
|
* <p>As this base class is not marked Serializable, the cache will be recreated
|
||||||
* after serialization - provided that the concrete subclass is Serializable.
|
* after serialization - provided that the concrete subclass is Serializable.
|
||||||
*/
|
*/
|
||||||
final Map<Object, Collection<CacheOperation>> attributeCache = new ConcurrentHashMap<Object, Collection<CacheOperation>>();
|
final Map<Object, Collection<CacheOperation>> attributeCache =
|
||||||
|
new ConcurrentHashMap<Object, Collection<CacheOperation>>(1024);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -39,16 +39,16 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||||
*/
|
*/
|
||||||
class ExpressionEvaluator {
|
class ExpressionEvaluator {
|
||||||
|
|
||||||
private SpelExpressionParser parser = new SpelExpressionParser();
|
private final SpelExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
// shared param discoverer since it caches data internally
|
// shared param discoverer since it caches data internally
|
||||||
private ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
private final ParameterNameDiscoverer paramNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
|
||||||
|
|
||||||
private Map<String, Expression> conditionCache = new ConcurrentHashMap<String, Expression>();
|
private final Map<String, Expression> conditionCache = new ConcurrentHashMap<String, Expression>(64);
|
||||||
|
|
||||||
private Map<String, Expression> keyCache = new ConcurrentHashMap<String, Expression>();
|
private final Map<String, Expression> keyCache = new ConcurrentHashMap<String, Expression>(64);
|
||||||
|
|
||||||
private Map<String, Method> targetMethodCache = new ConcurrentHashMap<String, Method>();
|
private final Map<String, Method> targetMethodCache = new ConcurrentHashMap<String, Method>(64);
|
||||||
|
|
||||||
|
|
||||||
public EvaluationContext createEvaluationContext(
|
public EvaluationContext createEvaluationContext(
|
||||||
|
|
|
@ -29,9 +29,8 @@ import org.springframework.cache.CacheManager;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class implementing the common {@link CacheManager}
|
* Abstract base class implementing the common {@link CacheManager} methods.
|
||||||
* methods. Useful for 'static' environments where the backing caches do
|
* Useful for 'static' environments where the backing caches do not change.
|
||||||
* not change.
|
|
||||||
*
|
*
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
@ -39,9 +38,9 @@ import org.springframework.util.Assert;
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractCacheManager implements CacheManager, InitializingBean {
|
public abstract class AbstractCacheManager implements CacheManager, InitializingBean {
|
||||||
|
|
||||||
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>();
|
private final ConcurrentMap<String, Cache> cacheMap = new ConcurrentHashMap<String, Cache>(16);
|
||||||
|
|
||||||
private Set<String> cacheNames = new LinkedHashSet<String>();
|
private Set<String> cacheNames = new LinkedHashSet<String>(16);
|
||||||
|
|
||||||
|
|
||||||
public void afterPropertiesSet() {
|
public void afterPropertiesSet() {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -39,8 +39,36 @@ import org.springframework.cache.CacheManager;
|
||||||
*/
|
*/
|
||||||
public class NoOpCacheManager implements CacheManager {
|
public class NoOpCacheManager implements CacheManager {
|
||||||
|
|
||||||
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>();
|
private final ConcurrentMap<String, Cache> caches = new ConcurrentHashMap<String, Cache>(16);
|
||||||
private Set<String> names = new LinkedHashSet<String>();
|
|
||||||
|
private final Set<String> cacheNames = new LinkedHashSet<String>(16);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation always returns a {@link Cache} implementation that will not store items.
|
||||||
|
* Additionally, the request cache will be remembered by the manager for consistency.
|
||||||
|
*/
|
||||||
|
public Cache getCache(String name) {
|
||||||
|
Cache cache = this.caches.get(name);
|
||||||
|
if (cache == null) {
|
||||||
|
this.caches.putIfAbsent(name, new NoOpCache(name));
|
||||||
|
synchronized (this.cacheNames) {
|
||||||
|
this.cacheNames.add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.caches.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This implementation returns the name of the caches previously requested.
|
||||||
|
*/
|
||||||
|
public Collection<String> getCacheNames() {
|
||||||
|
synchronized (this.cacheNames) {
|
||||||
|
return Collections.unmodifiableSet(this.cacheNames);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class NoOpCache implements Cache {
|
private static class NoOpCache implements Cache {
|
||||||
|
|
||||||
|
@ -61,7 +89,7 @@ public class NoOpCacheManager implements CacheManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getNativeCache() {
|
public Object getNativeCache() {
|
||||||
|
@ -72,30 +100,4 @@ public class NoOpCacheManager implements CacheManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* This implementation always returns a {@link Cache} implementation that will not
|
|
||||||
* store items. Additionally, the request cache will be remembered by the manager for consistency.
|
|
||||||
*/
|
|
||||||
public Cache getCache(String name) {
|
|
||||||
Cache cache = caches.get(name);
|
|
||||||
if (cache == null) {
|
|
||||||
caches.putIfAbsent(name, new NoOpCache(name));
|
|
||||||
synchronized (names) {
|
|
||||||
names.add(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return caches.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritDoc}
|
|
||||||
*
|
|
||||||
* This implementation returns the name of the caches previously requested.
|
|
||||||
*/
|
|
||||||
public Collection<String> getCacheNames() {
|
|
||||||
return Collections.unmodifiableSet(names);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||||
private transient BeanFactory beanFactory;
|
private transient BeanFactory beanFactory;
|
||||||
|
|
||||||
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
|
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -513,10 +513,6 @@ public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBean
|
||||||
|
|
||||||
protected boolean shareable = true;
|
protected boolean shareable = true;
|
||||||
|
|
||||||
private volatile boolean cached = false;
|
|
||||||
|
|
||||||
private volatile Object cachedFieldValue;
|
|
||||||
|
|
||||||
public ResourceElement(Member member, PropertyDescriptor pd) {
|
public ResourceElement(Member member, PropertyDescriptor pd) {
|
||||||
super(member, pd);
|
super(member, pd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public abstract class AbstractApplicationEventMulticaster implements Application
|
||||||
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
|
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
|
||||||
|
|
||||||
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
|
private final Map<ListenerCacheKey, ListenerRetriever> retrieverCache =
|
||||||
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>();
|
new ConcurrentHashMap<ListenerCacheKey, ListenerRetriever>(64);
|
||||||
|
|
||||||
private BeanFactory beanFactory;
|
private BeanFactory beanFactory;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -60,10 +60,10 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
|
||||||
|
|
||||||
private ExpressionParser expressionParser = new SpelExpressionParser();
|
private ExpressionParser expressionParser = new SpelExpressionParser();
|
||||||
|
|
||||||
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();
|
private final Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>(256);
|
||||||
|
|
||||||
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
private final Map<BeanExpressionContext, StandardEvaluationContext> evaluationCache =
|
||||||
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>();
|
new ConcurrentHashMap<BeanExpressionContext, StandardEvaluationContext>(8);
|
||||||
|
|
||||||
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
private final ParserContext beanExpressionParserContext = new ParserContext() {
|
||||||
public boolean isTemplate() {
|
public boolean isTemplate() {
|
||||||
|
|
|
@ -1387,7 +1387,7 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
||||||
*/
|
*/
|
||||||
private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor {
|
private class ApplicationListenerDetector implements MergedBeanDefinitionPostProcessor {
|
||||||
|
|
||||||
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>();
|
private final Map<String, Boolean> singletonNames = new ConcurrentHashMap<String, Boolean>(64);
|
||||||
|
|
||||||
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
|
||||||
if (beanDefinition.isSingleton()) {
|
if (beanDefinition.isSingleton()) {
|
||||||
|
|
|
@ -53,10 +53,10 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
private StringValueResolver embeddedValueResolver;
|
private StringValueResolver embeddedValueResolver;
|
||||||
|
|
||||||
private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters =
|
private final Map<AnnotationConverterKey, GenericConverter> cachedPrinters =
|
||||||
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>();
|
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
|
||||||
|
|
||||||
private final Map<AnnotationConverterKey, GenericConverter> cachedParsers =
|
private final Map<AnnotationConverterKey, GenericConverter> cachedParsers =
|
||||||
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>();
|
new ConcurrentHashMap<AnnotationConverterKey, GenericConverter>(64);
|
||||||
|
|
||||||
|
|
||||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||||
|
@ -214,11 +214,14 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
return sourceType.hasAnnotation(annotationType);
|
return sourceType.hasAnnotation(annotationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
AnnotationConverterKey converterKey = new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType());
|
AnnotationConverterKey converterKey =
|
||||||
|
new AnnotationConverterKey(sourceType.getAnnotation(annotationType), sourceType.getObjectType());
|
||||||
GenericConverter converter = cachedPrinters.get(converterKey);
|
GenericConverter converter = cachedPrinters.get(converterKey);
|
||||||
if (converter == null) {
|
if (converter == null) {
|
||||||
Printer<?> printer = annotationFormatterFactory.getPrinter(converterKey.getAnnotation(), converterKey.getFieldType());
|
Printer<?> printer = annotationFormatterFactory.getPrinter(
|
||||||
|
converterKey.getAnnotation(), converterKey.getFieldType());
|
||||||
converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this);
|
converter = new PrinterConverter(fieldType, printer, FormattingConversionService.this);
|
||||||
cachedPrinters.put(converterKey, converter);
|
cachedPrinters.put(converterKey, converter);
|
||||||
}
|
}
|
||||||
|
@ -226,7 +229,8 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " + String.class.getName() + ": " + annotationFormatterFactory;
|
return "@" + annotationType.getName() + " " + fieldType.getName() + " -> " +
|
||||||
|
String.class.getName() + ": " + annotationFormatterFactory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,11 +258,14 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
return targetType.hasAnnotation(annotationType);
|
return targetType.hasAnnotation(annotationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
AnnotationConverterKey converterKey = new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType());
|
AnnotationConverterKey converterKey =
|
||||||
|
new AnnotationConverterKey(targetType.getAnnotation(annotationType), targetType.getObjectType());
|
||||||
GenericConverter converter = cachedParsers.get(converterKey);
|
GenericConverter converter = cachedParsers.get(converterKey);
|
||||||
if (converter == null) {
|
if (converter == null) {
|
||||||
Parser<?> parser = annotationFormatterFactory.getParser(converterKey.getAnnotation(), converterKey.getFieldType());
|
Parser<?> parser = annotationFormatterFactory.getParser(
|
||||||
|
converterKey.getAnnotation(), converterKey.getFieldType());
|
||||||
converter = new ParserConverter(fieldType, parser, FormattingConversionService.this);
|
converter = new ParserConverter(fieldType, parser, FormattingConversionService.this);
|
||||||
cachedParsers.put(converterKey, converter);
|
cachedParsers.put(converterKey, converter);
|
||||||
}
|
}
|
||||||
|
@ -266,7 +273,8 @@ public class FormattingConversionService extends GenericConversionService
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.class.getName() + " -> @" + annotationType.getName() + " " + fieldType.getName() + ": " + annotationFormatterFactory;
|
return String.class.getName() + " -> @" + annotationType.getName() + " " +
|
||||||
|
fieldType.getName() + ": " + annotationFormatterFactory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,10 +42,9 @@ import org.springframework.util.ClassUtils;
|
||||||
* information in the method attributes to discover parameter names. Returns
|
* information in the method attributes to discover parameter names. Returns
|
||||||
* <code>null</code> if the class file was compiled without debug information.
|
* <code>null</code> if the class file was compiled without debug information.
|
||||||
*
|
*
|
||||||
* <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer
|
* <p>Uses ObjectWeb's ASM library for analyzing class files. Each discoverer instance
|
||||||
* instance caches the ASM discovered information for each introspected Class, in a
|
* caches the ASM discovered information for each introspected Class, in a thread-safe
|
||||||
* thread-safe manner. It is recommended to reuse discoverer instances
|
* manner. It is recommended to reuse ParameterNameDiscoverer instances as far as possible.
|
||||||
* as far as possible.
|
|
||||||
*
|
*
|
||||||
* @author Adrian Colyer
|
* @author Adrian Colyer
|
||||||
* @author Costin Leau
|
* @author Costin Leau
|
||||||
|
@ -62,7 +61,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
|
||||||
|
|
||||||
// the cache uses a nested index (value is a map) to keep the top level cache relatively small in size
|
// the cache uses a nested index (value is a map) to keep the top level cache relatively small in size
|
||||||
private final Map<Class<?>, Map<Member, String[]>> parameterNamesCache =
|
private final Map<Class<?>, Map<Member, String[]>> parameterNamesCache =
|
||||||
new ConcurrentHashMap<Class<?>, Map<Member, String[]>>();
|
new ConcurrentHashMap<Class<?>, Map<Member, String[]>>(32);
|
||||||
|
|
||||||
|
|
||||||
public String[] getParameterNames(Method method) {
|
public String[] getParameterNames(Method method) {
|
||||||
|
@ -111,7 +110,7 @@ public class LocalVariableTableParameterNameDiscoverer implements ParameterNameD
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
ClassReader classReader = new ClassReader(is);
|
ClassReader classReader = new ClassReader(is);
|
||||||
Map<Member, String[]> map = new ConcurrentHashMap<Member, String[]>();
|
Map<Member, String[]> map = new ConcurrentHashMap<Member, String[]>(32);
|
||||||
classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);
|
classReader.accept(new ParameterNameDiscoveringVisitor(clazz, map), 0);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -38,7 +38,7 @@ import org.springframework.util.StringValueResolver;
|
||||||
public class SimpleAliasRegistry implements AliasRegistry {
|
public class SimpleAliasRegistry implements AliasRegistry {
|
||||||
|
|
||||||
/** Map from alias to canonical name */
|
/** Map from alias to canonical name */
|
||||||
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>();
|
private final Map<String, String> aliasMap = new ConcurrentHashMap<String, String>(16);
|
||||||
|
|
||||||
|
|
||||||
public void registerAlias(String name, String alias) {
|
public void registerAlias(String name, String alias) {
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||||
private final Converters converters = new Converters();
|
private final Converters converters = new Converters();
|
||||||
|
|
||||||
private final Map<ConverterCacheKey, GenericConverter> converterCache =
|
private final Map<ConverterCacheKey, GenericConverter> converterCache =
|
||||||
new ConcurrentHashMap<ConverterCacheKey, GenericConverter>();
|
new ConcurrentHashMap<ConverterCacheKey, GenericConverter>(64);
|
||||||
|
|
||||||
|
|
||||||
// implementing ConverterRegistry
|
// implementing ConverterRegistry
|
||||||
|
@ -182,8 +182,8 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||||
* @param targetType the target type
|
* @param targetType the target type
|
||||||
* @return the converted value
|
* @return the converted value
|
||||||
* @throws ConversionException if a conversion exception occurred
|
* @throws ConversionException if a conversion exception occurred
|
||||||
* @throws IllegalArgumentException if targetType is null
|
* @throws IllegalArgumentException if targetType is null,
|
||||||
* @throws IllegalArgumentException if sourceType is null but source is not null
|
* or sourceType is null but source is not null
|
||||||
*/
|
*/
|
||||||
public Object convert(Object source, TypeDescriptor targetType) {
|
public Object convert(Object source, TypeDescriptor targetType) {
|
||||||
return convert(source, TypeDescriptor.forObject(source), targetType);
|
return convert(source, TypeDescriptor.forObject(source), targetType);
|
||||||
|
@ -480,7 +480,6 @@ public class GenericConversionService implements ConfigurableConversionService {
|
||||||
* @param sourceType the source type
|
* @param sourceType the source type
|
||||||
* @param targetType the target type
|
* @param targetType the target type
|
||||||
* @return a {@link GenericConverter} or <tt>null</tt>
|
* @return a {@link GenericConverter} or <tt>null</tt>
|
||||||
* @see #getTypeHierarchy(Class)
|
|
||||||
*/
|
*/
|
||||||
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
public GenericConverter find(TypeDescriptor sourceType, TypeDescriptor targetType) {
|
||||||
// Search the full type hierarchy
|
// Search the full type hierarchy
|
||||||
|
|
|
@ -46,11 +46,11 @@ import org.springframework.util.StringUtils;
|
||||||
*/
|
*/
|
||||||
public class ReflectivePropertyAccessor implements PropertyAccessor {
|
public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
|
|
||||||
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>();
|
private final Map<CacheKey, InvokerPair> readerCache = new ConcurrentHashMap<CacheKey, InvokerPair>(64);
|
||||||
|
|
||||||
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>();
|
private final Map<CacheKey, Member> writerCache = new ConcurrentHashMap<CacheKey, Member>(64);
|
||||||
|
|
||||||
private final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>();
|
private final Map<CacheKey, TypeDescriptor> typeDescriptorCache = new ConcurrentHashMap<CacheKey, TypeDescriptor>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +86,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
Field field = findField(name, type, target);
|
Field field = findField(name, type, target);
|
||||||
if (field != null) {
|
if (field != null) {
|
||||||
TypeDescriptor typeDescriptor = new TypeDescriptor(field);
|
TypeDescriptor typeDescriptor = new TypeDescriptor(field);
|
||||||
this.readerCache.put(cacheKey, new InvokerPair(field,typeDescriptor));
|
this.readerCache.put(cacheKey, new InvokerPair(field, typeDescriptor));
|
||||||
this.typeDescriptorCache.put(cacheKey, typeDescriptor);
|
this.typeDescriptorCache.put(cacheKey, typeDescriptor);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -264,15 +264,15 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
|
||||||
return TypeDescriptor.valueOf(Integer.TYPE);
|
return TypeDescriptor.valueOf(Integer.TYPE);
|
||||||
}
|
}
|
||||||
CacheKey cacheKey = new CacheKey(type, name);
|
CacheKey cacheKey = new CacheKey(type, name);
|
||||||
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
TypeDescriptor typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
||||||
if (typeDescriptor == null) {
|
if (typeDescriptor == null) {
|
||||||
// attempt to populate the cache entry
|
// attempt to populate the cache entry
|
||||||
try {
|
try {
|
||||||
if (canRead(context, target, name)) {
|
if (canRead(context, target, name)) {
|
||||||
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
||||||
}
|
}
|
||||||
else if (canWrite(context, target, name)) {
|
else if (canWrite(context, target, name)) {
|
||||||
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
typeDescriptor = this.typeDescriptorCache.get(cacheKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AccessException ex) {
|
catch (AccessException ex) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -60,7 +60,7 @@ public class JndiDestinationResolver extends JndiLocatorSupport implements Cachi
|
||||||
|
|
||||||
private DestinationResolver dynamicDestinationResolver = new DynamicDestinationResolver();
|
private DestinationResolver dynamicDestinationResolver = new DynamicDestinationResolver();
|
||||||
|
|
||||||
private final Map<String, Destination> destinationCache = new ConcurrentHashMap<String, Destination>();
|
private final Map<String, Destination> destinationCache = new ConcurrentHashMap<String, Destination>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,9 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.orm.hibernate3;
|
package org.springframework.orm.hibernate3;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.hibernate.FlushMode;
|
import org.hibernate.FlushMode;
|
||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
|
@ -44,10 +43,10 @@ public class SessionHolder extends ResourceHolderSupport {
|
||||||
private static final Object DEFAULT_KEY = new Object();
|
private static final Object DEFAULT_KEY = new Object();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This Map needs to be synchronized because there might be multi-threaded
|
* This Map needs to be concurrent because there might be multi-threaded
|
||||||
* access in the case of JTA with remote transaction propagation.
|
* access in the case of JTA with remote transaction propagation.
|
||||||
*/
|
*/
|
||||||
private final Map<Object, Session> sessionMap = Collections.synchronizedMap(new HashMap<Object, Session>(1));
|
private final Map<Object, Session> sessionMap = new ConcurrentHashMap<Object, Session>(1);
|
||||||
|
|
||||||
private Transaction transaction;
|
private Transaction transaction;
|
||||||
|
|
||||||
|
@ -89,12 +88,10 @@ public class SessionHolder extends ResourceHolderSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Session getAnySession() {
|
public Session getAnySession() {
|
||||||
synchronized (this.sessionMap) {
|
if (!this.sessionMap.isEmpty()) {
|
||||||
if (!this.sessionMap.isEmpty()) {
|
return this.sessionMap.values().iterator().next();
|
||||||
return this.sessionMap.values().iterator().next();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSession(Session session) {
|
public void addSession(Session session) {
|
||||||
|
@ -120,10 +117,8 @@ public class SessionHolder extends ResourceHolderSupport {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean doesNotHoldNonDefaultSession() {
|
public boolean doesNotHoldNonDefaultSession() {
|
||||||
synchronized (this.sessionMap) {
|
return this.sessionMap.isEmpty() ||
|
||||||
return this.sessionMap.isEmpty() ||
|
(this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
|
||||||
(this.sessionMap.size() == 1 && this.sessionMap.containsKey(DEFAULT_KEY));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -182,10 +182,10 @@ public class PersistenceAnnotationBeanPostProcessor
|
||||||
private transient ListableBeanFactory beanFactory;
|
private transient ListableBeanFactory beanFactory;
|
||||||
|
|
||||||
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
private transient final Map<Class<?>, InjectionMetadata> injectionMetadataCache =
|
||||||
new ConcurrentHashMap<Class<?>, InjectionMetadata>();
|
new ConcurrentHashMap<Class<?>, InjectionMetadata>(64);
|
||||||
|
|
||||||
private final Map<Object, EntityManager> extendedEntityManagersToClose =
|
private final Map<Object, EntityManager> extendedEntityManagersToClose =
|
||||||
new ConcurrentHashMap<Object, EntityManager>();
|
new ConcurrentHashMap<Object, EntityManager>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -18,27 +18,26 @@ package org.springframework.mock.jndi;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
|
|
||||||
import org.springframework.jndi.JndiTemplate;
|
import org.springframework.jndi.JndiTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple extension of the JndiTemplate class that always returns a given
|
* Simple extension of the JndiTemplate class that always returns a given object.
|
||||||
* object. Very useful for testing. Effectively a mock object.
|
*
|
||||||
*
|
* <p>Very useful for testing. Effectively a mock object.
|
||||||
|
*
|
||||||
* @author Rod Johnson
|
* @author Rod Johnson
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
*/
|
*/
|
||||||
public class ExpectedLookupTemplate extends JndiTemplate {
|
public class ExpectedLookupTemplate extends JndiTemplate {
|
||||||
|
|
||||||
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>();
|
private final Map<String, Object> jndiObjects = new ConcurrentHashMap<String, Object>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new JndiTemplate that will always return given objects for
|
* Construct a new JndiTemplate that will always return given objects for
|
||||||
* given names. To be populated through <code>addObject</code> calls.
|
* given names. To be populated through <code>addObject</code> calls.
|
||||||
*
|
|
||||||
* @see #addObject(String, Object)
|
* @see #addObject(String, Object)
|
||||||
*/
|
*/
|
||||||
public ExpectedLookupTemplate() {
|
public ExpectedLookupTemplate() {
|
||||||
|
@ -47,7 +46,6 @@ public class ExpectedLookupTemplate extends JndiTemplate {
|
||||||
/**
|
/**
|
||||||
* Construct a new JndiTemplate that will always return the given object,
|
* Construct a new JndiTemplate that will always return the given object,
|
||||||
* but honour only requests for the given name.
|
* but honour only requests for the given name.
|
||||||
*
|
|
||||||
* @param name the name the client is expected to look up
|
* @param name the name the client is expected to look up
|
||||||
* @param object the object that will be returned
|
* @param object the object that will be returned
|
||||||
*/
|
*/
|
||||||
|
@ -56,9 +54,7 @@ public class ExpectedLookupTemplate extends JndiTemplate {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given object to the list of JNDI objects that this template will
|
* Add the given object to the list of JNDI objects that this template will expose.
|
||||||
* expose.
|
|
||||||
*
|
|
||||||
* @param name the name the client is expected to look up
|
* @param name the name the client is expected to look up
|
||||||
* @param object the object that will be returned
|
* @param object the object that will be returned
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -44,7 +44,8 @@ class ContextCache {
|
||||||
/**
|
/**
|
||||||
* Map of context keys to Spring ApplicationContext instances.
|
* Map of context keys to Spring ApplicationContext instances.
|
||||||
*/
|
*/
|
||||||
private final Map<MergedContextConfiguration, ApplicationContext> contextMap = new ConcurrentHashMap<MergedContextConfiguration, ApplicationContext>();
|
private final Map<MergedContextConfiguration, ApplicationContext> contextMap =
|
||||||
|
new ConcurrentHashMap<MergedContextConfiguration, ApplicationContext>(64);
|
||||||
|
|
||||||
private int hitCount;
|
private int hitCount;
|
||||||
|
|
||||||
|
@ -69,7 +70,6 @@ class ContextCache {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return whether there is a cached context for the given key.
|
* Return whether there is a cached context for the given key.
|
||||||
*
|
|
||||||
* @param key the context key (never <code>null</code>)
|
* @param key the context key (never <code>null</code>)
|
||||||
*/
|
*/
|
||||||
boolean contains(MergedContextConfiguration key) {
|
boolean contains(MergedContextConfiguration key) {
|
||||||
|
@ -79,10 +79,8 @@ class ContextCache {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Obtain a cached ApplicationContext for the given key.
|
* Obtain a cached ApplicationContext for the given key.
|
||||||
*
|
|
||||||
* <p>The {@link #getHitCount() hit} and {@link #getMissCount() miss}
|
* <p>The {@link #getHitCount() hit} and {@link #getMissCount() miss}
|
||||||
* counts will be updated accordingly.
|
* counts will be updated accordingly.
|
||||||
*
|
|
||||||
* @param key the context key (never <code>null</code>)
|
* @param key the context key (never <code>null</code>)
|
||||||
* @return the corresponding ApplicationContext instance,
|
* @return the corresponding ApplicationContext instance,
|
||||||
* or <code>null</code> if not found in the cache.
|
* or <code>null</code> if not found in the cache.
|
||||||
|
@ -135,7 +133,6 @@ class ContextCache {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explicitly add an ApplicationContext instance to the cache under the given key.
|
* Explicitly add an ApplicationContext instance to the cache under the given key.
|
||||||
*
|
|
||||||
* @param key the context key (never <code>null</code>)
|
* @param key the context key (never <code>null</code>)
|
||||||
* @param context the ApplicationContext instance (never <code>null</code>)
|
* @param context the ApplicationContext instance (never <code>null</code>)
|
||||||
*/
|
*/
|
||||||
|
@ -147,7 +144,6 @@ class ContextCache {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the context with the given key.
|
* Remove the context with the given key.
|
||||||
*
|
|
||||||
* @param key the context key (never <code>null</code>)
|
* @param key the context key (never <code>null</code>)
|
||||||
* @return the corresponding ApplicationContext instance, or <code>null</code>
|
* @return the corresponding ApplicationContext instance, or <code>null</code>
|
||||||
* if not found in the cache.
|
* if not found in the cache.
|
||||||
|
@ -162,11 +158,9 @@ class ContextCache {
|
||||||
* {@link #remove removing} the context from the cache and explicitly
|
* {@link #remove removing} the context from the cache and explicitly
|
||||||
* {@link ConfigurableApplicationContext#close() closing} it if it is an
|
* {@link ConfigurableApplicationContext#close() closing} it if it is an
|
||||||
* instance of {@link ConfigurableApplicationContext}.
|
* instance of {@link ConfigurableApplicationContext}.
|
||||||
*
|
|
||||||
* <p>Generally speaking, you would only call this method if you change the
|
* <p>Generally speaking, you would only call this method if you change the
|
||||||
* state of a singleton bean, potentially affecting future interaction with
|
* state of a singleton bean, potentially affecting future interaction with
|
||||||
* the context.
|
* the context.
|
||||||
*
|
|
||||||
* @param key the context key (never <code>null</code>)
|
* @param key the context key (never <code>null</code>)
|
||||||
* @see #remove
|
* @see #remove
|
||||||
*/
|
*/
|
||||||
|
@ -192,11 +186,8 @@ class ContextCache {
|
||||||
* as the {@link #hitCount hit} and {@link #missCount miss} counts.
|
* as the {@link #hitCount hit} and {@link #missCount miss} counts.
|
||||||
*/
|
*/
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringCreator(this)//
|
return new ToStringCreator(this).append("size", size()).append("hitCount", getHitCount()).
|
||||||
.append("size", size())//
|
append("missCount", getMissCount()).toString();
|
||||||
.append("hitCount", getHitCount())//
|
|
||||||
.append("missCount", getMissCount())//
|
|
||||||
.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,12 +21,13 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
|
@ -111,7 +112,7 @@ public class TransactionalTestExecutionListener extends AbstractTestExecutionLis
|
||||||
protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource();
|
protected final TransactionAttributeSource attributeSource = new AnnotationTransactionAttributeSource();
|
||||||
|
|
||||||
private final Map<Method, TransactionContext> transactionContextCache =
|
private final Map<Method, TransactionContext> transactionContextCache =
|
||||||
Collections.synchronizedMap(new IdentityHashMap<Method, TransactionContext>());
|
new ConcurrentHashMap<Method, TransactionContext>(8);
|
||||||
|
|
||||||
private TransactionConfigurationAttributes configurationAttributes;
|
private TransactionConfigurationAttributes configurationAttributes;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -69,7 +69,7 @@ public abstract class AbstractFallbackTransactionAttributeSource implements Tran
|
||||||
* <p>As this base class is not marked Serializable, the cache will be recreated
|
* <p>As this base class is not marked Serializable, the cache will be recreated
|
||||||
* after serialization - provided that the concrete subclass is Serializable.
|
* after serialization - provided that the concrete subclass is Serializable.
|
||||||
*/
|
*/
|
||||||
final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<Object, TransactionAttribute>();
|
final Map<Object, TransactionAttribute> attributeCache = new ConcurrentHashMap<Object, TransactionAttribute>(1024);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,19 +27,19 @@ import org.springframework.http.converter.HttpMessageConversionException;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters} that
|
* Abstract base class for {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverters}
|
||||||
* use JAXB2. Creates {@link JAXBContext} object lazily.
|
* that use JAXB2. Creates {@link JAXBContext} object lazily.
|
||||||
*
|
*
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHttpMessageConverter<T> {
|
public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHttpMessageConverter<T> {
|
||||||
|
|
||||||
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>();
|
private final ConcurrentMap<Class, JAXBContext> jaxbContexts = new ConcurrentHashMap<Class, JAXBContext>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link Marshaller} for the given class.
|
* Create a new {@link Marshaller} for the given class.
|
||||||
*
|
|
||||||
* @param clazz the class to create the marshaller for
|
* @param clazz the class to create the marshaller for
|
||||||
* @return the {@code Marshaller}
|
* @return the {@code Marshaller}
|
||||||
* @throws HttpMessageConversionException in case of JAXB errors
|
* @throws HttpMessageConversionException in case of JAXB errors
|
||||||
|
@ -56,8 +56,7 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new {@link Unmarshaller} for the given class.
|
* Create a new {@link Unmarshaller} for the given class.
|
||||||
*
|
|
||||||
* @param clazz the class to create the unmarshaller for
|
* @param clazz the class to create the unmarshaller for
|
||||||
* @return the {@code Unmarshaller}
|
* @return the {@code Unmarshaller}
|
||||||
* @throws HttpMessageConversionException in case of JAXB errors
|
* @throws HttpMessageConversionException in case of JAXB errors
|
||||||
|
@ -74,19 +73,18 @@ public abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractXmlHt
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link JAXBContext} for the given class.
|
* Return a {@link JAXBContext} for the given class.
|
||||||
*
|
|
||||||
* @param clazz the class to return the context for
|
* @param clazz the class to return the context for
|
||||||
* @return the {@code JAXBContext}
|
* @return the {@code JAXBContext}
|
||||||
* @throws HttpMessageConversionException in case of JAXB errors
|
* @throws HttpMessageConversionException in case of JAXB errors
|
||||||
*/
|
*/
|
||||||
protected final JAXBContext getJaxbContext(Class clazz) {
|
protected final JAXBContext getJaxbContext(Class clazz) {
|
||||||
Assert.notNull(clazz, "'clazz' must not be null");
|
Assert.notNull(clazz, "'clazz' must not be null");
|
||||||
JAXBContext jaxbContext = jaxbContexts.get(clazz);
|
JAXBContext jaxbContext = this.jaxbContexts.get(clazz);
|
||||||
if (jaxbContext == null) {
|
if (jaxbContext == null) {
|
||||||
try {
|
try {
|
||||||
jaxbContext = JAXBContext.newInstance(clazz);
|
jaxbContext = JAXBContext.newInstance(clazz);
|
||||||
jaxbContexts.putIfAbsent(clazz, jaxbContext);
|
this.jaxbContexts.putIfAbsent(clazz, jaxbContext);
|
||||||
}
|
}
|
||||||
catch (JAXBException ex) {
|
catch (JAXBException ex) {
|
||||||
throw new HttpMessageConversionException(
|
throw new HttpMessageConversionException(
|
||||||
|
|
|
@ -13,10 +13,11 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.web.accept;
|
package org.springframework.web.accept;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -37,11 +38,12 @@ import org.springframework.util.MultiValueMap;
|
||||||
*/
|
*/
|
||||||
public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver {
|
public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExtensionResolver {
|
||||||
|
|
||||||
private final ConcurrentMap<String, MediaType> mediaTypes = new ConcurrentHashMap<String, MediaType>();
|
private final ConcurrentMap<String, MediaType> mediaTypes = new ConcurrentHashMap<String, MediaType>(64);
|
||||||
|
|
||||||
private final MultiValueMap<MediaType, String> fileExtensions = new LinkedMultiValueMap<MediaType, String>();
|
private final MultiValueMap<MediaType, String> fileExtensions = new LinkedMultiValueMap<MediaType, String>();
|
||||||
|
|
||||||
private final List<String> allFileExtensions = new ArrayList<String>();
|
private final List<String> allFileExtensions = new LinkedList<String>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an instance with the given mappings between extensions and media types.
|
* Create an instance with the given mappings between extensions and media types.
|
||||||
|
@ -89,4 +91,4 @@ public class MappingMediaTypeFileExtensionResolver implements MediaTypeFileExten
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -19,10 +19,11 @@ package org.springframework.web.bind.annotation.support;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.core.BridgeMethodResolver;
|
import org.springframework.core.BridgeMethodResolver;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
@ -64,7 +65,8 @@ public class HandlerMethodResolver {
|
||||||
|
|
||||||
private final Set<Class> sessionAttributeTypes = new HashSet<Class>();
|
private final Set<Class> sessionAttributeTypes = new HashSet<Class>();
|
||||||
|
|
||||||
private final Set<String> actualSessionAttributeNames = Collections.synchronizedSet(new HashSet<String>(4));
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<String, Boolean> actualSessionAttributeNames = new ConcurrentHashMap<String, Boolean>(4);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +154,7 @@ public class HandlerMethodResolver {
|
||||||
|
|
||||||
public boolean isSessionAttribute(String attrName, Class attrType) {
|
public boolean isSessionAttribute(String attrName, Class attrType) {
|
||||||
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
|
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
|
||||||
this.actualSessionAttributeNames.add(attrName);
|
this.actualSessionAttributeNames.put(attrName, Boolean.TRUE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -161,7 +163,7 @@ public class HandlerMethodResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<String> getActualSessionAttributeNames() {
|
public Set<String> getActualSessionAttributeNames() {
|
||||||
return this.actualSessionAttributeNames;
|
return this.actualSessionAttributeNames.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
private final BeanExpressionContext expressionContext;
|
private final BeanExpressionContext expressionContext;
|
||||||
|
|
||||||
private Map<MethodParameter, NamedValueInfo> namedValueInfoCache =
|
private Map<MethodParameter, NamedValueInfo> namedValueInfoCache =
|
||||||
new ConcurrentHashMap<MethodParameter, NamedValueInfo>();
|
new ConcurrentHashMap<MethodParameter, NamedValueInfo>(256);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param beanFactory a bean factory to use for resolving ${...} placeholder
|
* @param beanFactory a bean factory to use for resolving ${...} placeholder
|
||||||
|
@ -80,11 +80,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
throws Exception {
|
throws Exception {
|
||||||
|
|
||||||
Class<?> paramType = parameter.getParameterType();
|
Class<?> paramType = parameter.getParameterType();
|
||||||
|
|
||||||
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
|
NamedValueInfo namedValueInfo = getNamedValueInfo(parameter);
|
||||||
|
|
||||||
Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
|
Object arg = resolveName(namedValueInfo.name, parameter, webRequest);
|
||||||
|
|
||||||
if (arg == null) {
|
if (arg == null) {
|
||||||
if (namedValueInfo.defaultValue != null) {
|
if (namedValueInfo.defaultValue != null) {
|
||||||
arg = resolveDefaultValue(namedValueInfo.defaultValue);
|
arg = resolveDefaultValue(namedValueInfo.defaultValue);
|
||||||
|
@ -121,7 +119,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
/**
|
/**
|
||||||
* Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically
|
* Create the {@link NamedValueInfo} object for the given method parameter. Implementations typically
|
||||||
* retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}.
|
* retrieve the method annotation by means of {@link MethodParameter#getParameterAnnotation(Class)}.
|
||||||
*
|
|
||||||
* @param parameter the method parameter
|
* @param parameter the method parameter
|
||||||
* @return the named value information
|
* @return the named value information
|
||||||
*/
|
*/
|
||||||
|
@ -146,7 +143,6 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
* @param name the name of the value being resolved
|
* @param name the name of the value being resolved
|
||||||
* @param parameter the method parameter to resolve to an argument value
|
* @param parameter the method parameter to resolve to an argument value
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
*
|
|
||||||
* @return the resolved argument. May be {@code null}
|
* @return the resolved argument. May be {@code null}
|
||||||
* @throws Exception in case of errors
|
* @throws Exception in case of errors
|
||||||
*/
|
*/
|
||||||
|
@ -203,9 +199,9 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
*/
|
*/
|
||||||
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
|
protected void handleResolvedValue(Object arg, String name, MethodParameter parameter,
|
||||||
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
|
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the information about a named value, including name, whether it's required and a default value.
|
* Represents the information about a named value, including name, whether it's required and a default value.
|
||||||
*/
|
*/
|
||||||
|
@ -223,4 +219,5 @@ public abstract class AbstractNamedValueMethodArgumentResolver implements Handle
|
||||||
this.defaultValue = defaultValue;
|
this.defaultValue = defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -46,10 +46,10 @@ public class ExceptionHandlerMethodResolver {
|
||||||
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
|
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis");
|
||||||
|
|
||||||
private final Map<Class<? extends Throwable>, Method> mappedMethods =
|
private final Map<Class<? extends Throwable>, Method> mappedMethods =
|
||||||
new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
|
||||||
|
|
||||||
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache =
|
private final Map<Class<? extends Throwable>, Method> exceptionLookupCache =
|
||||||
new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A constructor that finds {@link ExceptionHandler} methods in the given type.
|
* A constructor that finds {@link ExceptionHandler} methods in the given type.
|
||||||
|
|
|
@ -17,11 +17,11 @@
|
||||||
package org.springframework.web.method.annotation;
|
package org.springframework.web.method.annotation;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
@ -50,10 +50,12 @@ public class SessionAttributesHandler {
|
||||||
|
|
||||||
private final Set<Class<?>> attributeTypes = new HashSet<Class<?>>();
|
private final Set<Class<?>> attributeTypes = new HashSet<Class<?>>();
|
||||||
|
|
||||||
private final Set<String> knownAttributeNames = Collections.synchronizedSet(new HashSet<String>(4));
|
// using a ConcurrentHashMap as a Set
|
||||||
|
private final Map<String, Boolean> knownAttributeNames = new ConcurrentHashMap<String, Boolean>(4);
|
||||||
|
|
||||||
private final SessionAttributeStore sessionAttributeStore;
|
private final SessionAttributeStore sessionAttributeStore;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance for a controller type. Session attribute names and
|
* Create a new instance for a controller type. Session attribute names and
|
||||||
* types are extracted from the {@code @SessionAttributes} annotation, if
|
* types are extracted from the {@code @SessionAttributes} annotation, if
|
||||||
|
@ -71,7 +73,9 @@ public class SessionAttributesHandler {
|
||||||
this.attributeTypes.addAll(Arrays.<Class<?>>asList(annotation.types()));
|
this.attributeTypes.addAll(Arrays.<Class<?>>asList(annotation.types()));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.knownAttributeNames.addAll(this.attributeNames);
|
for (String attributeName : this.attributeNames) {
|
||||||
|
this.knownAttributeNames.put(attributeName, Boolean.TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -96,7 +100,7 @@ public class SessionAttributesHandler {
|
||||||
public boolean isHandlerSessionAttribute(String attributeName, Class<?> attributeType) {
|
public boolean isHandlerSessionAttribute(String attributeName, Class<?> attributeType) {
|
||||||
Assert.notNull(attributeName, "Attribute name must not be null");
|
Assert.notNull(attributeName, "Attribute name must not be null");
|
||||||
if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) {
|
if (this.attributeNames.contains(attributeName) || this.attributeTypes.contains(attributeType)) {
|
||||||
this.knownAttributeNames.add(attributeName);
|
this.knownAttributeNames.put(attributeName, Boolean.TRUE);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -130,7 +134,7 @@ public class SessionAttributesHandler {
|
||||||
*/
|
*/
|
||||||
public Map<String, Object> retrieveAttributes(WebRequest request) {
|
public Map<String, Object> retrieveAttributes(WebRequest request) {
|
||||||
Map<String, Object> attributes = new HashMap<String, Object>();
|
Map<String, Object> attributes = new HashMap<String, Object>();
|
||||||
for (String name : this.knownAttributeNames) {
|
for (String name : this.knownAttributeNames.keySet()) {
|
||||||
Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
|
Object value = this.sessionAttributeStore.retrieveAttribute(request, name);
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
attributes.put(name, value);
|
attributes.put(name, value);
|
||||||
|
@ -146,7 +150,7 @@ public class SessionAttributesHandler {
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
*/
|
*/
|
||||||
public void cleanupAttributes(WebRequest request) {
|
public void cleanupAttributes(WebRequest request) {
|
||||||
for (String attributeName : this.knownAttributeNames) {
|
for (String attributeName : this.knownAttributeNames.keySet()) {
|
||||||
this.sessionAttributeStore.cleanupAttribute(request, attributeName);
|
this.sessionAttributeStore.cleanupAttribute(request, attributeName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,4 +165,4 @@ public class SessionAttributesHandler {
|
||||||
return this.sessionAttributeStore.retrieveAttribute(request, attributeName);
|
return this.sessionAttributeStore.retrieveAttribute(request, attributeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,15 @@
|
||||||
|
|
||||||
package org.springframework.web.method.support;
|
package org.springframework.web.method.support;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||||
|
@ -41,10 +42,11 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||||
protected final Log logger = LogFactory.getLog(getClass());
|
protected final Log logger = LogFactory.getLog(getClass());
|
||||||
|
|
||||||
private final List<HandlerMethodArgumentResolver> argumentResolvers =
|
private final List<HandlerMethodArgumentResolver> argumentResolvers =
|
||||||
new ArrayList<HandlerMethodArgumentResolver>();
|
new LinkedList<HandlerMethodArgumentResolver>();
|
||||||
|
|
||||||
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
|
private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
|
||||||
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>();
|
new ConcurrentHashMap<MethodParameter, HandlerMethodArgumentResolver>(256);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a read-only list with the contained resolvers, or an empty list.
|
* Return a read-only list with the contained resolvers, or an empty list.
|
||||||
|
@ -81,7 +83,7 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
|
||||||
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
|
private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
|
||||||
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
|
HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
for (HandlerMethodArgumentResolver methodArgumentResolver : argumentResolvers) {
|
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
|
logger.trace("Testing if argument resolver [" + methodArgumentResolver + "] supports [" +
|
||||||
parameter.getGenericParameterType() + "]");
|
parameter.getGenericParameterType() + "]");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2011 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -151,7 +151,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
|
||||||
private BeanExpressionContext expressionContext;
|
private BeanExpressionContext expressionContext;
|
||||||
|
|
||||||
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
|
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
|
||||||
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>();
|
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>(64);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2010 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,7 +30,6 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.portlet.ClientDataRequest;
|
import javax.portlet.ClientDataRequest;
|
||||||
import javax.portlet.Event;
|
import javax.portlet.Event;
|
||||||
import javax.portlet.EventRequest;
|
import javax.portlet.EventRequest;
|
||||||
|
@ -76,11 +75,14 @@ import org.springframework.web.servlet.View;
|
||||||
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||||
|
|
||||||
// dummy method placeholder
|
// dummy method placeholder
|
||||||
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
|
private static final Method NO_METHOD_FOUND =
|
||||||
|
ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
|
||||||
|
|
||||||
|
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
|
||||||
|
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>(64);
|
||||||
|
|
||||||
private WebArgumentResolver[] customArgumentResolvers;
|
private WebArgumentResolver[] customArgumentResolvers;
|
||||||
|
|
||||||
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache = new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set a custom ArgumentResolvers to use for special method parameter types.
|
* Set a custom ArgumentResolvers to use for special method parameter types.
|
||||||
|
@ -134,18 +136,18 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
|
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
|
||||||
final Class<?> handlerType = handler.getClass();
|
final Class<?> handlerType = handler.getClass();
|
||||||
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
||||||
Method handlerMethod = null;
|
Method handlerMethod;
|
||||||
|
|
||||||
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
|
|
||||||
|
|
||||||
|
Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType);
|
||||||
if (handlers != null) {
|
if (handlers != null) {
|
||||||
handlerMethod = handlers.get(thrownExceptionType);
|
handlerMethod = handlers.get(thrownExceptionType);
|
||||||
if (handlerMethod != null) {
|
if (handlerMethod != null) {
|
||||||
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
|
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
else {
|
||||||
exceptionHandlerCache.put(handlerType, handlers);
|
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
|
||||||
|
this.exceptionHandlerCache.put(handlerType, handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
|
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
|
||||||
|
@ -205,7 +207,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uses the {@link DepthComparator} to find the best matching method
|
* Uses the {@link ExceptionDepthComparator} to find the best matching method.
|
||||||
* @return the best matching method or {@code null}.
|
* @return the best matching method or {@code null}.
|
||||||
*/
|
*/
|
||||||
private Method getBestMatchingMethod(
|
private Method getBestMatchingMethod(
|
||||||
|
@ -217,7 +219,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
Class<? extends Throwable> closestMatch =
|
Class<? extends Throwable> closestMatch =
|
||||||
ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException);
|
ExceptionDepthComparator.findClosestMatch(resolverMethods.keySet(), thrownException);
|
||||||
Method method = resolverMethods.get(closestMatch);
|
Method method = resolverMethods.get(closestMatch);
|
||||||
return ((method == null) || (NO_METHOD_FOUND == method)) ? null : method;
|
return (method == null || NO_METHOD_FOUND == method ? null : method);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -27,7 +27,7 @@ import org.springframework.web.context.WebApplicationContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tiles2 {@link org.apache.tiles.preparer.PreparerFactory} implementation
|
* Tiles3 {@link org.apache.tiles.preparer.PreparerFactory} implementation
|
||||||
* that expects preparer class names and builds preparer instances for those,
|
* that expects preparer class names and builds preparer instances for those,
|
||||||
* creating them through the Spring ApplicationContext in order to apply
|
* creating them through the Spring ApplicationContext in order to apply
|
||||||
* Spring container callbacks and configured Spring BeanPostProcessors.
|
* Spring container callbacks and configured Spring BeanPostProcessors.
|
||||||
|
@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext;
|
||||||
*/
|
*/
|
||||||
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
|
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
|
||||||
|
|
||||||
/** Cache of shared ViewPreparer instances: bean name --> bean instance */
|
/** Cache of shared ViewPreparer instances: bean name -> bean instance */
|
||||||
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>();
|
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -54,7 +54,7 @@ public class UrlFilenameViewController extends AbstractUrlViewController {
|
||||||
private String suffix = "";
|
private String suffix = "";
|
||||||
|
|
||||||
/** Request URL path String --> view name String */
|
/** Request URL path String --> view name String */
|
||||||
private final Map<String, String> viewNameCache = new ConcurrentHashMap<String, String>();
|
private final Map<String, String> viewNameCache = new ConcurrentHashMap<String, String>(256);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,7 +35,6 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
@ -46,6 +45,7 @@ import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
import org.springframework.beans.factory.BeanFactoryAware;
|
import org.springframework.beans.factory.BeanFactoryAware;
|
||||||
|
@ -56,7 +56,6 @@ import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.ParameterNameDiscoverer;
|
import org.springframework.core.ParameterNameDiscoverer;
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.core.convert.support.DefaultConversionService;
|
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpInputMessage;
|
import org.springframework.http.HttpInputMessage;
|
||||||
|
@ -188,9 +187,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
||||||
private BeanExpressionContext expressionContext;
|
private BeanExpressionContext expressionContext;
|
||||||
|
|
||||||
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache =
|
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache =
|
||||||
new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>();
|
new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>(64);
|
||||||
|
|
||||||
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>();
|
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>(64);
|
||||||
|
|
||||||
|
|
||||||
public AnnotationMethodHandlerAdapter() {
|
public AnnotationMethodHandlerAdapter() {
|
||||||
|
|
|
@ -32,7 +32,6 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
@ -82,7 +81,7 @@ import org.springframework.web.servlet.support.RequestContextUtils;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*
|
*
|
||||||
* @deprecated in Spring 3.2 in favor of
|
* @deprecated as of Spring 3.2, in favor of
|
||||||
* {@link org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver}
|
* {@link org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver ExceptionHandlerExceptionResolver}
|
||||||
*/
|
*/
|
||||||
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||||
|
@ -91,7 +90,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
|
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", (Class<?>[]) null);
|
||||||
|
|
||||||
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
|
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
|
||||||
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>();
|
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>(64);
|
||||||
|
|
||||||
private WebArgumentResolver[] customArgumentResolvers;
|
private WebArgumentResolver[] customArgumentResolvers;
|
||||||
|
|
||||||
|
@ -162,8 +161,7 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
||||||
Method handlerMethod = null;
|
Method handlerMethod = null;
|
||||||
|
|
||||||
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
|
Map<Class<? extends Throwable>, Method> handlers = this.exceptionHandlerCache.get(handlerType);
|
||||||
|
|
||||||
if (handlers != null) {
|
if (handlers != null) {
|
||||||
handlerMethod = handlers.get(thrownExceptionType);
|
handlerMethod = handlers.get(thrownExceptionType);
|
||||||
if (handlerMethod != null) {
|
if (handlerMethod != null) {
|
||||||
|
@ -171,8 +169,8 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>(16);
|
||||||
exceptionHandlerCache.put(handlerType, handlers);
|
this.exceptionHandlerCache.put(handlerType, handlers);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
|
final Map<Class<? extends Throwable>, Method> matchedHandlers = new HashMap<Class<? extends Throwable>, Method>();
|
||||||
|
|
|
@ -24,7 +24,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.xml.transform.Source;
|
import javax.xml.transform.Source;
|
||||||
|
@ -39,7 +38,6 @@ import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
|
||||||
import org.springframework.web.accept.ContentNegotiationManager;
|
import org.springframework.web.accept.ContentNegotiationManager;
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
import org.springframework.web.context.request.ServletWebRequest;
|
import org.springframework.web.context.request.ServletWebRequest;
|
||||||
|
@ -82,7 +80,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
||||||
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
|
private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager();
|
||||||
|
|
||||||
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
|
private final Map<Class<?>, ExceptionHandlerMethodResolver> exceptionHandlerCache =
|
||||||
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>();
|
new ConcurrentHashMap<Class<?>, ExceptionHandlerMethodResolver>(64);
|
||||||
|
|
||||||
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
|
private final Map<ControllerAdviceBean, ExceptionHandlerMethodResolver> exceptionHandlerAdviceCache =
|
||||||
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();
|
new LinkedHashMap<ControllerAdviceBean, ExceptionHandlerMethodResolver>();
|
||||||
|
|
|
@ -157,14 +157,14 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||||
|
|
||||||
|
|
||||||
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache =
|
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache =
|
||||||
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>();
|
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>(64);
|
||||||
|
|
||||||
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<Class<?>, Set<Method>>();
|
private final Map<Class<?>, Set<Method>> initBinderCache = new ConcurrentHashMap<Class<?>, Set<Method>>(64);
|
||||||
|
|
||||||
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache =
|
private final Map<ControllerAdviceBean, Set<Method>> initBinderAdviceCache =
|
||||||
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
|
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
|
||||||
|
|
||||||
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<Class<?>, Set<Method>>();
|
private final Map<Class<?>, Set<Method>> modelAttributeCache = new ConcurrentHashMap<Class<?>, Set<Method>>(64);
|
||||||
|
|
||||||
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache =
|
private final Map<ControllerAdviceBean, Set<Method>> modelAttributeAdviceCache =
|
||||||
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
|
new LinkedHashMap<ControllerAdviceBean, Set<Method>>();
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2008 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -43,7 +43,7 @@ public class InternalPathMethodNameResolver extends AbstractUrlMethodNameResolve
|
||||||
private String suffix = "";
|
private String suffix = "";
|
||||||
|
|
||||||
/** Request URL path String --> method name String */
|
/** Request URL path String --> method name String */
|
||||||
private final Map<String, String> methodNameCache = new ConcurrentHashMap<String, String>();
|
private final Map<String, String> methodNameCache = new ConcurrentHashMap<String, String>(16);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2012 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -38,8 +38,8 @@ import org.springframework.web.context.WebApplicationContext;
|
||||||
*/
|
*/
|
||||||
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
|
public class SimpleSpringPreparerFactory extends AbstractSpringPreparerFactory {
|
||||||
|
|
||||||
/** Cache of shared ViewPreparer instances: bean name --> bean instance */
|
/** Cache of shared ViewPreparer instances: bean name -> bean instance */
|
||||||
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>();
|
private final Map<String, ViewPreparer> sharedPreparers = new ConcurrentHashMap<String, ViewPreparer>(16);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
Loading…
Reference in New Issue