SPR-7703
- minor performance improvements to servlet and portlet handlers
This commit is contained in:
parent
caf1a0875a
commit
01e79cfedd
|
@ -29,6 +29,8 @@ import java.util.LinkedHashMap;
|
|||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.portlet.ActionRequest;
|
||||
import javax.portlet.ActionResponse;
|
||||
import javax.portlet.ClientDataRequest;
|
||||
|
@ -58,6 +60,7 @@ import org.springframework.beans.factory.config.BeanExpressionContext;
|
|||
import org.springframework.beans.factory.config.BeanExpressionResolver;
|
||||
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
@ -149,8 +152,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
|
|||
|
||||
private BeanExpressionContext expressionContext;
|
||||
|
||||
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
|
||||
new HashMap<Class<?>, PortletHandlerMethodResolver>();
|
||||
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache = new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>();
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -25,10 +25,11 @@ import java.lang.reflect.Method;
|
|||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.portlet.ClientDataRequest;
|
||||
import javax.portlet.Event;
|
||||
import javax.portlet.EventRequest;
|
||||
|
@ -40,6 +41,9 @@ import javax.portlet.PortletRequest;
|
|||
import javax.portlet.PortletResponse;
|
||||
import javax.portlet.PortletSession;
|
||||
import javax.portlet.WindowState;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.springframework.core.ExceptionDepthComparator;
|
||||
import org.springframework.core.GenericTypeResolver;
|
||||
|
@ -70,8 +74,13 @@ import org.springframework.web.servlet.View;
|
|||
*/
|
||||
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
|
||||
// dummy method placeholder
|
||||
private static final Method NO_METHOD_FOUND = ClassUtils
|
||||
.getMethodIfAvailable(System.class, "currentTimeMillis", null);
|
||||
|
||||
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.
|
||||
|
@ -125,8 +134,22 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
|||
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
|
||||
final Class<?> handlerType = handler.getClass();
|
||||
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
||||
final Map<Class<? extends Throwable>, Method> resolverMethods =
|
||||
new LinkedHashMap<Class<? extends Throwable>, Method>();
|
||||
|
||||
Method handlerMethod = null;
|
||||
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache
|
||||
.get(handlerType);
|
||||
|
||||
if (handlers != null) {
|
||||
handlerMethod = handlers.get(thrownExceptionType);
|
||||
if (handlerMethod != null) {
|
||||
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
|
||||
}
|
||||
} else {
|
||||
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
||||
exceptionHandlerCache.put(handlerType, handlers);
|
||||
}
|
||||
|
||||
final Map<Class<? extends Throwable>, Method> resolverMethods = handlers;
|
||||
|
||||
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
|
|
|
@ -27,13 +27,14 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
@ -44,7 +45,6 @@ import javax.servlet.http.HttpSession;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
|
@ -182,8 +182,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
|||
|
||||
private BeanExpressionContext expressionContext;
|
||||
|
||||
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache =
|
||||
new HashMap<Class<?>, ServletHandlerMethodResolver>();
|
||||
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache = new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>();
|
||||
|
||||
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>();
|
||||
|
||||
|
||||
public AnnotationMethodHandlerAdapter() {
|
||||
|
@ -390,7 +391,16 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
|||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
|
||||
throws Exception {
|
||||
|
||||
if (AnnotationUtils.findAnnotation(handler.getClass(), SessionAttributes.class) != null) {
|
||||
Class<?> clazz = ClassUtils.getUserClass(handler);
|
||||
Boolean annotated = sessionAnnotatedClassesCache.get(clazz);
|
||||
|
||||
if (annotated == null) {
|
||||
annotated = Boolean.valueOf(AnnotationUtils.findAnnotation(handler
|
||||
.getClass(), SessionAttributes.class) != null);
|
||||
sessionAnnotatedClassesCache.put(clazz, annotated);
|
||||
}
|
||||
|
||||
if (annotated) {
|
||||
// Always prevent caching in case of session attribute management.
|
||||
checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);
|
||||
// Prepare cached set of session attributes names.
|
||||
|
@ -498,7 +508,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
|
|||
*/
|
||||
private class ServletHandlerMethodResolver extends HandlerMethodResolver {
|
||||
|
||||
private final Map<Method, RequestMappingInfo> mappings = new HashMap<Method, RequestMappingInfo>();
|
||||
private final Map<Method, RequestMappingInfo> mappings = new ConcurrentHashMap<Method, RequestMappingInfo>();
|
||||
|
||||
private ServletHandlerMethodResolver(Class<?> handlerType) {
|
||||
init(handlerType);
|
||||
|
|
|
@ -27,10 +27,11 @@ import java.security.Principal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
@ -82,6 +83,12 @@ import org.springframework.web.servlet.support.RequestContextUtils;
|
|||
*/
|
||||
public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExceptionResolver {
|
||||
|
||||
// dummy method placeholder
|
||||
private static final Method NO_METHOD_FOUND = ClassUtils.getMethodIfAvailable(System.class, "currentTimeMillis", null);
|
||||
|
||||
private final Map<Class<?>, Map<Class<? extends Throwable>, Method>> exceptionHandlerCache =
|
||||
new ConcurrentHashMap<Class<?>, Map<Class<? extends Throwable>, Method>>();
|
||||
|
||||
private WebArgumentResolver[] customArgumentResolvers;
|
||||
|
||||
private HttpMessageConverter<?>[] messageConverters =
|
||||
|
@ -147,10 +154,24 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
|||
* @return the best matching method; or <code>null</code> if none is found
|
||||
*/
|
||||
private Method findBestExceptionHandlerMethod(Object handler, final Exception thrownException) {
|
||||
final Class<?> handlerType = handler.getClass();
|
||||
final Class<?> handlerType = ClassUtils.getUserClass(handler);
|
||||
final Class<? extends Throwable> thrownExceptionType = thrownException.getClass();
|
||||
final Map<Class<? extends Throwable>, Method> resolverMethods =
|
||||
new LinkedHashMap<Class<? extends Throwable>, Method>();
|
||||
Method handlerMethod = null;
|
||||
|
||||
Map<Class<? extends Throwable>, Method> handlers = exceptionHandlerCache.get(handlerType);
|
||||
|
||||
if (handlers != null) {
|
||||
handlerMethod = handlers.get(thrownExceptionType);
|
||||
if (handlerMethod != null) {
|
||||
return (handlerMethod == NO_METHOD_FOUND ? null : handlerMethod);
|
||||
}
|
||||
}
|
||||
else {
|
||||
handlers = new ConcurrentHashMap<Class<? extends Throwable>, Method>();
|
||||
exceptionHandlerCache.put(handlerType, handlers);
|
||||
}
|
||||
|
||||
final Map<Class<? extends Throwable>, Method> resolverMethods = handlers;
|
||||
|
||||
ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
|
||||
public void doWith(Method method) {
|
||||
|
@ -174,7 +195,9 @@ public class AnnotationMethodHandlerExceptionResolver extends AbstractHandlerExc
|
|||
}
|
||||
});
|
||||
|
||||
return getBestMatchingMethod(resolverMethods, thrownException);
|
||||
handlerMethod = getBestMatchingMethod(resolverMethods, thrownException);
|
||||
handlers.put(thrownExceptionType, (handlerMethod == null ? NO_METHOD_FOUND : handlerMethod));
|
||||
return handlerMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue