diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java index 5795032b2fa..e1ec9e5ea28 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java @@ -29,13 +29,14 @@ import org.springframework.messaging.handler.HandlerMethod; import org.springframework.util.ReflectionUtils; /** - * Invokes the handler method for a given message after resolving - * its method argument values through registered {@link HandlerMethodArgumentResolver}s. + * Invokes the handler method for a given message after resolving its method argument + * values through registered {@link HandlerMethodArgumentResolver}s. * *
Use {@link #setMessageMethodArgumentResolvers(HandlerMethodArgumentResolver)} * to customize the list of argument resolvers. * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 4.0 */ public class InvocableHandlerMethod extends HandlerMethod { @@ -66,7 +67,9 @@ public class InvocableHandlerMethod extends HandlerMethod { * @param parameterTypes the method parameter types * @throws NoSuchMethodException when the method cannot be found */ - public InvocableHandlerMethod(Object bean, String methodName, Class>... parameterTypes) throws NoSuchMethodException { + public InvocableHandlerMethod(Object bean, String methodName, Class>... parameterTypes) + throws NoSuchMethodException { + super(bean, methodName, parameterTypes); } @@ -93,12 +96,12 @@ public class InvocableHandlerMethod extends HandlerMethod { * @throws Exception raised if no suitable argument resolver can be found, * or the method raised an exception */ - public final Object invoke(Message> message, Object... providedArgs) throws Exception { + public Object invoke(Message> message, Object... providedArgs) throws Exception { Object[] args = getMethodArgumentValues(message, providedArgs); if (logger.isTraceEnabled()) { logger.trace("Resolved arguments: " + Arrays.asList(args)); } - Object returnValue = invoke(args); + Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Returned value: " + returnValue); } @@ -172,10 +175,11 @@ public class InvocableHandlerMethod extends HandlerMethod { return null; } + /** * Invoke the handler method with the given argument values. */ - private Object invoke(Object... args) throws Exception { + protected Object doInvoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(getBridgedMethod()); try { return getBridgedMethod().invoke(getBean(), args); diff --git a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java index 130a928ec86..6ce16e50bbe 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java @@ -32,17 +32,18 @@ import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.HandlerMethod; /** - * Provides a method for invoking the handler method for a given request after resolving its method argument - * values through registered {@link HandlerMethodArgumentResolver}s. + * Provides a method for invoking the handler method for a given request after resolving its + * method argument values through registered {@link HandlerMethodArgumentResolver}s. * - *
Argument resolution often requires a {@link WebDataBinder} for data binding or for type conversion. - * Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to supply a binder factory to pass to - * argument resolvers. + *
Argument resolution often requires a {@link WebDataBinder} for data binding or for type + * conversion. Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to supply + * a binder factory to pass to argument resolvers. * - *
Use {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)} to customize - * the list of argument resolvers. + *
Use {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)} + * to customize the list of argument resolvers. * * @author Rossen Stoyanchev + * @author Juergen Hoeller * @since 3.1 */ public class InvocableHandlerMethod extends HandlerMethod { @@ -75,7 +76,9 @@ public class InvocableHandlerMethod extends HandlerMethod { * @param parameterTypes the method parameter types * @throws NoSuchMethodException when the method cannot be found */ - public InvocableHandlerMethod(Object bean, String methodName, Class>... parameterTypes) throws NoSuchMethodException { + public InvocableHandlerMethod(Object bean, String methodName, Class>... parameterTypes) + throws NoSuchMethodException { + super(bean, methodName, parameterTypes); } @@ -107,18 +110,20 @@ public class InvocableHandlerMethod extends HandlerMethod { /** - * Invoke the method after resolving its argument values in the context of the given request.
Argument - * values are commonly resolved through {@link HandlerMethodArgumentResolver}s. The {@code provideArgs} - * parameter however may supply argument values to be used directly, i.e. without argument resolution. - * Examples of provided argument values include a {@link WebDataBinder}, a {@link SessionStatus}, or - * a thrown exception instance. Provided argument values are checked before argument resolvers. + * Invoke the method after resolving its argument values in the context of the given request. + *
Argument values are commonly resolved through {@link HandlerMethodArgumentResolver}s. + * The {@code provideArgs} parameter however may supply argument values to be used directly, + * i.e. without argument resolution. Examples of provided argument values include a + * {@link WebDataBinder}, a {@link SessionStatus}, or a thrown exception instance. + * Provided argument values are checked before argument resolvers. * @param request the current request * @param mavContainer the ModelAndViewContainer for this request * @param providedArgs "given" arguments matched by type, not resolved * @return the raw value returned by the invoked method - * @exception Exception raised if no suitable argument resolver can be found, or the method raised an exception + * @exception Exception raised if no suitable argument resolver can be found, + * or if the method raised an exception */ - public final Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, + public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); @@ -129,7 +134,7 @@ public class InvocableHandlerMethod extends HandlerMethod { sb.append(Arrays.asList(args)); logger.trace(sb.toString()); } - Object returnValue = invoke(args); + Object returnValue = doInvoke(args); if (logger.isTraceEnabled()) { logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]"); } @@ -206,10 +211,11 @@ public class InvocableHandlerMethod extends HandlerMethod { return null; } + /** * Invoke the handler method with the given argument values. */ - private Object invoke(Object... args) throws Exception { + protected Object doInvoke(Object... args) throws Exception { ReflectionUtils.makeAccessible(getBridgedMethod()); try { return getBridgedMethod().invoke(getBean(), args); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java index 422e681c18d..d48b6502a75 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ServletInvocableHandlerMethod.java @@ -88,6 +88,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { } } + /** * Register {@link HandlerMethodReturnValueHandler} instances to use to * handle return values. @@ -99,16 +100,14 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { /** * Invokes the method and handles the return value through one of the * configured {@link HandlerMethodReturnValueHandler}s. - * * @param webRequest the current request * @param mavContainer the ModelAndViewContainer for this request - * @param providedArgs "given" arguments matched by type, not resolved + * @param providedArgs "given" arguments matched by type (not resolved) */ - public final void invokeAndHandle(ServletWebRequest webRequest, + public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception { Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs); - setResponseStatus(webRequest); if (returnValue == null) { @@ -123,9 +122,9 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { } mavContainer.setRequestHandled(false); - try { - this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest); + this.returnValueHandlers.handleReturnValue( + returnValue, getReturnValueType(returnValue), mavContainer, webRequest); } catch (Exception ex) { if (logger.isTraceEnabled()) { @@ -165,20 +164,20 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { * Does this method have the response status instruction? */ private boolean hasResponseStatus() { - return this.responseStatus != null; + return (this.responseStatus != null); } private String getReturnValueHandlingErrorMessage(String message, Object returnValue) { StringBuilder sb = new StringBuilder(message); if (returnValue != null) { - sb.append(" [type=" + returnValue.getClass().getName() + "] "); + sb.append(" [type=").append(returnValue.getClass().getName()).append("]"); } - sb.append("[value=" + returnValue + "]"); + sb.append(" [value=").append(returnValue).append("]"); return getDetailedErrorMessage(sb.toString()); } /** - * Create a nested ServletInvocableHandlerMethod sub-class that returns the + * Create a nested ServletInvocableHandlerMethod subclass that returns the * the given value (or raises an Exception if the value is one) rather than * actually invoking the controller method. This is useful when processing * async return values (e.g. Callable, DeferredResult, ListenableFuture). @@ -189,7 +188,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { /** - * A nested sub-class of {@code ServletInvocableHandlerMethod} that uses a + * A nested subclass of {@code ServletInvocableHandlerMethod} that uses a * simple {@link Callable} instead of the original controller as the handler in * order to return the fixed (concurrent) result value given to it. Effectively * "resumes" processing with the asynchronously produced return value. @@ -198,7 +197,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod { private final MethodParameter returnType; - public ConcurrentResultHandlerMethod(final Object result, ConcurrentResultMethodParameter returnType) { super(new Callable