diff --git a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java index 9de90e4576..c93d3dfeb3 100644 --- a/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java +++ b/spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -125,10 +125,7 @@ public class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean - *
  • {@link Message} to get access to the complete message being processed.
  • - *
  • {@link Payload}-annotated method arguments to extract the payload of - * a message and optionally convert it using a - * {@link org.springframework.messaging.converter.MessageConverter}. - * The presence of the annotation is not required since it is assumed by default - * for method arguments that are not annotated. Payload method arguments annotated - * with Validation annotations (like - * {@link org.springframework.validation.annotation.Validated}) will be subject to - * JSR-303 validation.
  • - *
  • {@link Header}-annotated method arguments to extract a specific - * header value along with type conversion with a - * {@link org.springframework.core.convert.converter.Converter} if necessary.
  • - *
  • {@link Headers}-annotated argument that must also be assignable to - * {@link java.util.Map} for getting access to all headers.
  • - *
  • {@link org.springframework.messaging.MessageHeaders} arguments for - * getting access to all headers.
  • - *
  • {@link org.springframework.messaging.support.MessageHeaderAccessor} or - * with STOMP over WebSocket support also sub-classes such as - * {@link org.springframework.messaging.simp.SimpMessageHeaderAccessor} - * for convenient access to all method arguments.
  • - *
  • {@link DestinationVariable}-annotated arguments for access to template - * variable values extracted from the message destination (e.g. /hotels/{hotel}). - * Variable values will be converted to the declared method argument type.
  • - *
  • {@link java.security.Principal} method arguments are supported with - * STOMP over WebSocket messages. It reflects the user logged in to the - * WebSocket session on which the message was received. Regular HTTP-based - * authentication (e.g. Spring Security based) can be used to secure the - * HTTP handshake that initiates WebSocket sessions.
  • + *
  • {@link Message} to get access to the complete message being processed.
  • + *
  • {@link Payload}-annotated method arguments to extract the payload of + * a message and optionally convert it using a + * {@link org.springframework.messaging.converter.MessageConverter}. + * The presence of the annotation is not required since it is assumed by default + * for method arguments that are not annotated. Payload method arguments annotated + * with Validation annotations (like + * {@link org.springframework.validation.annotation.Validated}) will be subject to + * JSR-303 validation.
  • + *
  • {@link Header}-annotated method arguments to extract a specific + * header value along with type conversion with a + * {@link org.springframework.core.convert.converter.Converter} if necessary.
  • + *
  • {@link Headers}-annotated argument that must also be assignable to + * {@link java.util.Map} for getting access to all headers.
  • + *
  • {@link org.springframework.messaging.MessageHeaders} arguments for + * getting access to all headers.
  • + *
  • {@link org.springframework.messaging.support.MessageHeaderAccessor} or + * with STOMP over WebSocket support also sub-classes such as + * {@link org.springframework.messaging.simp.SimpMessageHeaderAccessor} + * for convenient access to all method arguments.
  • + *
  • {@link DestinationVariable}-annotated arguments for access to template + * variable values extracted from the message destination (e.g. /hotels/{hotel}). + * Variable values will be converted to the declared method argument type.
  • + *
  • {@link java.security.Principal} method arguments are supported with + * STOMP over WebSocket messages. It reflects the user logged in to the + * WebSocket session on which the message was received. Regular HTTP-based + * authentication (e.g. Spring Security based) can be used to secure the + * HTTP handshake that initiates WebSocket sessions.
  • * *

    By default the return value is wrapped as a message and sent to the destination * specified with an {@link SendTo} method-level annotation. @@ -78,7 +78,6 @@ import org.springframework.messaging.Message; * * @author Rossen Stoyanchev * @since 4.0 - * * @see org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler */ @Target({ElementType.TYPE, ElementType.METHOD}) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java index 7efaf91ab2..f0ac130781 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractHandlerMapping.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,7 +19,6 @@ package org.springframework.web.servlet.handler; import java.util.ArrayList; import java.util.Arrays; import java.util.List; - import javax.servlet.http.HttpServletRequest; import org.springframework.beans.BeansException; @@ -204,29 +203,28 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport *

    Will be invoked before {@link #initInterceptors()} adapts the specified * interceptors into {@link HandlerInterceptor} instances. *

    The default implementation is empty. - * @param interceptors the configured interceptor List (never {@code null}), - * allowing to add further interceptors before as well as after the existing - * interceptors + * @param interceptors the configured interceptor List (never {@code null}), allowing + * to add further interceptors before as well as after the existing interceptors */ protected void extendInterceptors(List interceptors) { } /** - * Detects beans of type {@link MappedInterceptor} and adds them to the list of mapped interceptors. - * This is done in addition to any {@link MappedInterceptor}s that may have been provided via - * {@link #setInterceptors(Object[])}. Subclasses can override this method to change that. - * - * @param mappedInterceptors an empty list to add MappedInterceptor types to + * Detect beans of type {@link MappedInterceptor} and add them to the list of mapped interceptors. + *

    This is called in addition to any {@link MappedInterceptor}s that may have been provided + * via {@link #setInterceptors}, by default adding all beans of type {@link MappedInterceptor} + * from the current context and its ancestors. Subclasses can override and refine this policy. + * @param mappedInterceptors an empty list to add {@link MappedInterceptor} instances to */ protected void detectMappedInterceptors(List mappedInterceptors) { mappedInterceptors.addAll( BeanFactoryUtils.beansOfTypeIncludingAncestors( - getApplicationContext(),MappedInterceptor.class, true, false).values()); + getApplicationContext(), MappedInterceptor.class, true, false).values()); } /** - * Initialize the specified interceptors, checking for {@link MappedInterceptor}s and adapting - * HandlerInterceptors where necessary. + * Initialize the specified interceptors, checking for {@link MappedInterceptor}s and + * adapting {@link HandlerInterceptor}s and {@link WebRequestInterceptor}s if necessary. * @see #setInterceptors * @see #adaptInterceptor */ @@ -238,19 +236,20 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null"); } if (interceptor instanceof MappedInterceptor) { - mappedInterceptors.add((MappedInterceptor) interceptor); + this.mappedInterceptors.add((MappedInterceptor) interceptor); } else { - adaptedInterceptors.add(adaptInterceptor(interceptor)); + this.adaptedInterceptors.add(adaptInterceptor(interceptor)); } } } } /** - * Adapt the given interceptor object to the HandlerInterceptor interface. - *

    Supported interceptor types are HandlerInterceptor and WebRequestInterceptor. - * Each given WebRequestInterceptor will be wrapped in a WebRequestHandlerInterceptorAdapter. + * Adapt the given interceptor object to the {@link HandlerInterceptor} interface. + *

    By default, the supported interceptor types are {@link HandlerInterceptor} + * and {@link WebRequestInterceptor}. Each given {@link WebRequestInterceptor} + * will be wrapped in a {@link WebRequestHandlerInterceptorAdapter}. * Can be overridden in subclasses. * @param interceptor the specified interceptor object * @return the interceptor wrapped as HandlerInterceptor @@ -271,12 +270,12 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport } /** - * Return the adapted interceptors as HandlerInterceptor array. - * @return the array of HandlerInterceptors, or {@code null} if none + * Return the adapted interceptors as {@link HandlerInterceptor} array. + * @return the array of {@link HandlerInterceptor}s, or {@code null} if none */ protected final HandlerInterceptor[] getAdaptedInterceptors() { - int count = adaptedInterceptors.size(); - return (count > 0) ? adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null; + int count = this.adaptedInterceptors.size(); + return (count > 0 ? this.adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null); } /** @@ -284,8 +283,8 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport * @return the array of {@link MappedInterceptor}s, or {@code null} if none */ protected final MappedInterceptor[] getMappedInterceptors() { - int count = mappedInterceptors.size(); - return (count > 0) ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null; + int count = this.mappedInterceptors.size(); + return (count > 0 ? this.mappedInterceptors.toArray(new MappedInterceptor[count]) : null); } /** @@ -326,31 +325,32 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport protected abstract Object getHandlerInternal(HttpServletRequest request) throws Exception; /** - * Build a HandlerExecutionChain for the given handler, including applicable interceptors. - *

    The default implementation simply builds a standard HandlerExecutionChain with - * the given handler, the handler mapping's common interceptors, and any {@link MappedInterceptor}s - * matching to the current request URL. Subclasses may - * override this in order to extend/rearrange the list of interceptors. - *

    NOTE: The passed-in handler object may be a raw handler or a pre-built - * HandlerExecutionChain. This method should handle those two cases explicitly, - * either building a new HandlerExecutionChain or extending the existing chain. - *

    For simply adding an interceptor, consider calling {@code super.getHandlerExecutionChain} - * and invoking {@link HandlerExecutionChain#addInterceptor} on the returned chain object. + * Build a {@link HandlerExecutionChain} for the given handler, including + * applicable interceptors. + *

    The default implementation builds a standard {@link HandlerExecutionChain} + * with the given handler, the handler mapping's common interceptors, and any + * {@link MappedInterceptor}s matching to the current request URL. Subclasses + * may override this in order to extend/rearrange the list of interceptors. + *

    NOTE: The passed-in handler object may be a raw handler or a + * pre-built {@link HandlerExecutionChain}. This method should handle those + * two cases explicitly, either building a new {@link HandlerExecutionChain} + * or extending the existing chain. + *

    For simply adding an interceptor in a custom subclass, consider calling + * {@code super.getHandlerExecutionChain(handler, request)} and invoking + * {@link HandlerExecutionChain#addInterceptor} on the returned chain object. * @param handler the resolved handler instance (never {@code null}) * @param request current HTTP request * @return the HandlerExecutionChain (never {@code null}) * @see #getAdaptedInterceptors() */ protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) { - HandlerExecutionChain chain = - (handler instanceof HandlerExecutionChain) ? - (HandlerExecutionChain) handler : new HandlerExecutionChain(handler); - + HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ? + (HandlerExecutionChain) handler : new HandlerExecutionChain(handler)); chain.addInterceptors(getAdaptedInterceptors()); - String lookupPath = urlPathHelper.getLookupPathForRequest(request); - for (MappedInterceptor mappedInterceptor : mappedInterceptors) { - if (mappedInterceptor.matches(lookupPath, pathMatcher)) { + String lookupPath = this.urlPathHelper.getLookupPathForRequest(request); + for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) { + if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) { chain.addInterceptor(mappedInterceptor.getInterceptor()); } } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java index 17d13855c0..c9a213db66 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java @@ -66,6 +66,7 @@ public class RequestMappingHandlerAdapterTests { private StaticWebApplicationContext webAppContext; + @BeforeClass public static void setupOnce() { RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter(); @@ -86,23 +87,24 @@ public class RequestMappingHandlerAdapterTests { this.response = new MockHttpServletResponse(); } + @Test public void cacheControlWithoutSessionAttributes() throws Exception { HandlerMethod handlerMethod = handlerMethod(new SimpleController(), "handle"); - this.handlerAdapter.afterPropertiesSet(); this.handlerAdapter.setCacheSeconds(100); - this.handlerAdapter.handle(this.request, this.response, handlerMethod); + this.handlerAdapter.afterPropertiesSet(); - assertTrue(response.getHeader("Cache-Control").toString().contains("max-age")); + this.handlerAdapter.handle(this.request, this.response, handlerMethod); + assertTrue(response.getHeader("Cache-Control").contains("max-age")); } @Test public void cacheControlWithSessionAttributes() throws Exception { SessionAttributeController handler = new SessionAttributeController(); - this.handlerAdapter.afterPropertiesSet(); this.handlerAdapter.setCacheSeconds(100); - this.handlerAdapter.handle(this.request, this.response, handlerMethod(handler, "handle")); + this.handlerAdapter.afterPropertiesSet(); + this.handlerAdapter.handle(this.request, this.response, handlerMethod(handler, "handle")); assertEquals("no-cache", this.response.getHeader("Cache-Control")); } @@ -226,6 +228,7 @@ public class RequestMappingHandlerAdapterTests { } } + @SessionAttributes("attr1") private static class SessionAttributeController { @@ -234,6 +237,7 @@ public class RequestMappingHandlerAdapterTests { } } + @SuppressWarnings("unused") private static class RedirectAttributeController { @@ -243,6 +247,7 @@ public class RequestMappingHandlerAdapterTests { } } + @ControllerAdvice private static class ModelAttributeAdvice { @@ -253,6 +258,7 @@ public class RequestMappingHandlerAdapterTests { } } + @ControllerAdvice({"org.springframework.web.servlet.mvc.method.annotation","java.lang"}) private static class ModelAttributePackageAdvice { @@ -262,6 +268,7 @@ public class RequestMappingHandlerAdapterTests { } } + @ControllerAdvice("java.lang") private static class ModelAttributeNotUsedPackageAdvice { @@ -270,4 +277,5 @@ public class RequestMappingHandlerAdapterTests { model.addAttribute("attr3", "gAttr3"); } } -} \ No newline at end of file + +}