From 18540debf6ae0ef4de9feda2b7caee457233e08f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 27 Jul 2011 22:38:32 +0000 Subject: [PATCH] backported locking enhancements for @MVC processing (SPR-7703) --- .../AnnotationMethodHandlerAdapter.java | 27 ++++++++--------- .../AnnotationMethodHandlerAdapter.java | 29 ++++++++++++++----- 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index 46e641bbe4f..c9953871efe 100644 --- a/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2011 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ 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; @@ -150,7 +151,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator private BeanExpressionContext expressionContext; private final Map, PortletHandlerMethodResolver> methodResolverCache = - new HashMap, PortletHandlerMethodResolver>(); + new ConcurrentHashMap, PortletHandlerMethodResolver>(); /** @@ -300,6 +301,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator } } + protected ModelAndView doHandle(PortletRequest request, PortletResponse response, Object handler) throws Exception { ExtendedModelMap implicitModel = null; @@ -391,17 +393,19 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator */ private PortletHandlerMethodResolver getMethodResolver(Object handler) { Class handlerClass = ClassUtils.getUserClass(handler); - synchronized (this.methodResolverCache) { - PortletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass); - if (resolver == null) { - resolver = new PortletHandlerMethodResolver(handlerClass); - this.methodResolverCache.put(handlerClass, resolver); + PortletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass); + if (resolver == null) { + synchronized (this.methodResolverCache) { + resolver = this.methodResolverCache.get(handlerClass); + if (resolver == null) { + resolver = new PortletHandlerMethodResolver(handlerClass); + this.methodResolverCache.put(handlerClass, resolver); + } } - return resolver; } + return resolver; } - /** * Template method for creating a new PortletRequestDataBinder instance. *

The default implementation creates a standard PortletRequestDataBinder. @@ -413,11 +417,8 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator * @return the PortletRequestDataBinder instance to use * @throws Exception in case of invalid state or arguments * @see PortletRequestDataBinder#bind(javax.portlet.PortletRequest) - * @see PortletRequestDataBinder#convertIfNecessary(Object, Class, MethodParameter) */ - protected PortletRequestDataBinder createBinder( - PortletRequest request, Object target, String objectName) throws Exception { - + protected PortletRequestDataBinder createBinder(PortletRequest request, Object target, String objectName) throws Exception { return new PortletRequestDataBinder(target, objectName); } diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index 84419286194..0197bbed174 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -34,6 +34,7 @@ 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; @@ -183,7 +184,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator private BeanExpressionContext expressionContext; private final Map, ServletHandlerMethodResolver> methodResolverCache = - new HashMap, ServletHandlerMethodResolver>(); + new ConcurrentHashMap, ServletHandlerMethodResolver>(); + + private final Map, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap, Boolean>(); public AnnotationMethodHandlerAdapter() { @@ -390,7 +393,14 @@ 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 annotatedWithSessionAttributes = this.sessionAnnotatedClassesCache.get(clazz); + if (annotatedWithSessionAttributes == null) { + annotatedWithSessionAttributes = (AnnotationUtils.findAnnotation(clazz, SessionAttributes.class) != null); + this.sessionAnnotatedClassesCache.put(clazz, annotatedWithSessionAttributes); + } + + if (annotatedWithSessionAttributes) { // Always prevent caching in case of session attribute management. checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true); // Prepare cached set of session attributes names. @@ -448,14 +458,17 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator */ private ServletHandlerMethodResolver getMethodResolver(Object handler) { Class handlerClass = ClassUtils.getUserClass(handler); - synchronized (this.methodResolverCache) { - ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass); - if (resolver == null) { - resolver = new ServletHandlerMethodResolver(handlerClass); - this.methodResolverCache.put(handlerClass, resolver); + ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass); + if (resolver == null) { + synchronized (this.methodResolverCache) { + resolver = this.methodResolverCache.get(handlerClass); + if (resolver == null) { + resolver = new ServletHandlerMethodResolver(handlerClass); + this.methodResolverCache.put(handlerClass, resolver); + } } - return resolver; } + return resolver; }