Skip to content

Commit 18540de

Browse files
committed
backported locking enhancements for @MVC processing (SPR-7703)
1 parent 7605707 commit 18540de

File tree

2 files changed

+35
-21
lines changed

2 files changed

+35
-21
lines changed

org.springframework.web.portlet/src/main/java/org/springframework/web/portlet/mvc/annotation/AnnotationMethodHandlerAdapter.java

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2010 the original author or authors.
2+
* Copyright 2002-2011 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -29,6 +29,7 @@
2929
import java.util.Locale;
3030
import java.util.Map;
3131
import java.util.Set;
32+
import java.util.concurrent.ConcurrentHashMap;
3233
import javax.portlet.ActionRequest;
3334
import javax.portlet.ActionResponse;
3435
import javax.portlet.ClientDataRequest;
@@ -150,7 +151,7 @@ public class AnnotationMethodHandlerAdapter extends PortletContentGenerator
150151
private BeanExpressionContext expressionContext;
151152

152153
private final Map<Class<?>, PortletHandlerMethodResolver> methodResolverCache =
153-
new HashMap<Class<?>, PortletHandlerMethodResolver>();
154+
new ConcurrentHashMap<Class<?>, PortletHandlerMethodResolver>();
154155

155156

156157
/**
@@ -300,6 +301,7 @@ public void handleEvent(EventRequest request, EventResponse response, Object han
300301
}
301302
}
302303

304+
303305
protected ModelAndView doHandle(PortletRequest request, PortletResponse response, Object handler) throws Exception {
304306
ExtendedModelMap implicitModel = null;
305307

@@ -391,17 +393,19 @@ private ModelAndView invokeHandlerMethod(
391393
*/
392394
private PortletHandlerMethodResolver getMethodResolver(Object handler) {
393395
Class handlerClass = ClassUtils.getUserClass(handler);
394-
synchronized (this.methodResolverCache) {
395-
PortletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
396-
if (resolver == null) {
397-
resolver = new PortletHandlerMethodResolver(handlerClass);
398-
this.methodResolverCache.put(handlerClass, resolver);
396+
PortletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
397+
if (resolver == null) {
398+
synchronized (this.methodResolverCache) {
399+
resolver = this.methodResolverCache.get(handlerClass);
400+
if (resolver == null) {
401+
resolver = new PortletHandlerMethodResolver(handlerClass);
402+
this.methodResolverCache.put(handlerClass, resolver);
403+
}
399404
}
400-
return resolver;
401405
}
406+
return resolver;
402407
}
403408

404-
405409
/**
406410
* Template method for creating a new PortletRequestDataBinder instance.
407411
* <p>The default implementation creates a standard PortletRequestDataBinder.
@@ -413,11 +417,8 @@ private PortletHandlerMethodResolver getMethodResolver(Object handler) {
413417
* @return the PortletRequestDataBinder instance to use
414418
* @throws Exception in case of invalid state or arguments
415419
* @see PortletRequestDataBinder#bind(javax.portlet.PortletRequest)
416-
* @see PortletRequestDataBinder#convertIfNecessary(Object, Class, MethodParameter)
417420
*/
418-
protected PortletRequestDataBinder createBinder(
419-
PortletRequest request, Object target, String objectName) throws Exception {
420-
421+
protected PortletRequestDataBinder createBinder(PortletRequest request, Object target, String objectName) throws Exception {
421422
return new PortletRequestDataBinder(target, objectName);
422423
}
423424

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import java.util.Locale;
3535
import java.util.Map;
3636
import java.util.Set;
37+
import java.util.concurrent.ConcurrentHashMap;
3738
import javax.servlet.ServletException;
3839
import javax.servlet.ServletRequest;
3940
import javax.servlet.ServletResponse;
@@ -183,7 +184,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
183184
private BeanExpressionContext expressionContext;
184185

185186
private final Map<Class<?>, ServletHandlerMethodResolver> methodResolverCache =
186-
new HashMap<Class<?>, ServletHandlerMethodResolver>();
187+
new ConcurrentHashMap<Class<?>, ServletHandlerMethodResolver>();
188+
189+
private final Map<Class<?>, Boolean> sessionAnnotatedClassesCache = new ConcurrentHashMap<Class<?>, Boolean>();
187190

188191

189192
public AnnotationMethodHandlerAdapter() {
@@ -390,7 +393,14 @@ public boolean supports(Object handler) {
390393
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
391394
throws Exception {
392395

393-
if (AnnotationUtils.findAnnotation(handler.getClass(), SessionAttributes.class) != null) {
396+
Class<?> clazz = ClassUtils.getUserClass(handler);
397+
Boolean annotatedWithSessionAttributes = this.sessionAnnotatedClassesCache.get(clazz);
398+
if (annotatedWithSessionAttributes == null) {
399+
annotatedWithSessionAttributes = (AnnotationUtils.findAnnotation(clazz, SessionAttributes.class) != null);
400+
this.sessionAnnotatedClassesCache.put(clazz, annotatedWithSessionAttributes);
401+
}
402+
403+
if (annotatedWithSessionAttributes) {
394404
// Always prevent caching in case of session attribute management.
395405
checkAndPrepare(request, response, this.cacheSecondsForSessionAttributeHandlers, true);
396406
// Prepare cached set of session attributes names.
@@ -448,14 +458,17 @@ public long getLastModified(HttpServletRequest request, Object handler) {
448458
*/
449459
private ServletHandlerMethodResolver getMethodResolver(Object handler) {
450460
Class handlerClass = ClassUtils.getUserClass(handler);
451-
synchronized (this.methodResolverCache) {
452-
ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
453-
if (resolver == null) {
454-
resolver = new ServletHandlerMethodResolver(handlerClass);
455-
this.methodResolverCache.put(handlerClass, resolver);
461+
ServletHandlerMethodResolver resolver = this.methodResolverCache.get(handlerClass);
462+
if (resolver == null) {
463+
synchronized (this.methodResolverCache) {
464+
resolver = this.methodResolverCache.get(handlerClass);
465+
if (resolver == null) {
466+
resolver = new ServletHandlerMethodResolver(handlerClass);
467+
this.methodResolverCache.put(handlerClass, resolver);
468+
}
456469
}
457-
return resolver;
458470
}
471+
return resolver;
459472
}
460473

461474

0 commit comments

Comments
 (0)