Relaxed final declarations and protected doInvoke methods
Issue: SPR-12484
This commit is contained in:
parent
efb114d49a
commit
2496d68e9f
|
|
@ -29,13 +29,14 @@ import org.springframework.messaging.handler.HandlerMethod;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the handler method for a given message after resolving
|
* Invokes the handler method for a given message after resolving its method argument
|
||||||
* its method argument values through registered {@link HandlerMethodArgumentResolver}s.
|
* values through registered {@link HandlerMethodArgumentResolver}s.
|
||||||
*
|
*
|
||||||
* <p>Use {@link #setMessageMethodArgumentResolvers(HandlerMethodArgumentResolver)}
|
* <p>Use {@link #setMessageMethodArgumentResolvers(HandlerMethodArgumentResolver)}
|
||||||
* to customize the list of argument resolvers.
|
* to customize the list of argument resolvers.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
public class InvocableHandlerMethod extends HandlerMethod {
|
public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
|
|
@ -66,7 +67,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
* @param parameterTypes the method parameter types
|
* @param parameterTypes the method parameter types
|
||||||
* @throws NoSuchMethodException when the method cannot be found
|
* @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);
|
super(bean, methodName, parameterTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -93,12 +96,12 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
* @throws Exception raised if no suitable argument resolver can be found,
|
* @throws Exception raised if no suitable argument resolver can be found,
|
||||||
* or the method raised an exception
|
* 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);
|
Object[] args = getMethodArgumentValues(message, providedArgs);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Resolved arguments: " + Arrays.asList(args));
|
logger.trace("Resolved arguments: " + Arrays.asList(args));
|
||||||
}
|
}
|
||||||
Object returnValue = invoke(args);
|
Object returnValue = doInvoke(args);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Returned value: " + returnValue);
|
logger.trace("Returned value: " + returnValue);
|
||||||
}
|
}
|
||||||
|
|
@ -172,10 +175,11 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the handler method with the given argument values.
|
* 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());
|
ReflectionUtils.makeAccessible(getBridgedMethod());
|
||||||
try {
|
try {
|
||||||
return getBridgedMethod().invoke(getBean(), args);
|
return getBridgedMethod().invoke(getBean(), args);
|
||||||
|
|
|
||||||
|
|
@ -32,17 +32,18 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a method for invoking the handler method for a given request after resolving its method argument
|
* Provides a method for invoking the handler method for a given request after resolving its
|
||||||
* values through registered {@link HandlerMethodArgumentResolver}s.
|
* method argument values through registered {@link HandlerMethodArgumentResolver}s.
|
||||||
*
|
*
|
||||||
* <p>Argument resolution often requires a {@link WebDataBinder} for data binding or for type conversion.
|
* <p>Argument resolution often requires a {@link WebDataBinder} for data binding or for type
|
||||||
* Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to supply a binder factory to pass to
|
* conversion. Use the {@link #setDataBinderFactory(WebDataBinderFactory)} property to supply
|
||||||
* argument resolvers.
|
* a binder factory to pass to argument resolvers.
|
||||||
*
|
*
|
||||||
* <p>Use {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)} to customize
|
* <p>Use {@link #setHandlerMethodArgumentResolvers(HandlerMethodArgumentResolverComposite)}
|
||||||
* the list of argument resolvers.
|
* to customize the list of argument resolvers.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Juergen Hoeller
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class InvocableHandlerMethod extends HandlerMethod {
|
public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
|
|
@ -75,7 +76,9 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
* @param parameterTypes the method parameter types
|
* @param parameterTypes the method parameter types
|
||||||
* @throws NoSuchMethodException when the method cannot be found
|
* @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);
|
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. <p>Argument
|
* Invoke the method after resolving its argument values in the context of the given request.
|
||||||
* values are commonly resolved through {@link HandlerMethodArgumentResolver}s. The {@code provideArgs}
|
* <p>Argument values are commonly resolved through {@link HandlerMethodArgumentResolver}s.
|
||||||
* parameter however may supply argument values to be used directly, i.e. without argument resolution.
|
* The {@code provideArgs} parameter however may supply argument values to be used directly,
|
||||||
* Examples of provided argument values include a {@link WebDataBinder}, a {@link SessionStatus}, or
|
* i.e. without argument resolution. Examples of provided argument values include a
|
||||||
* a thrown exception instance. Provided argument values are checked before argument resolvers.
|
* {@link WebDataBinder}, a {@link SessionStatus}, or a thrown exception instance.
|
||||||
|
* Provided argument values are checked before argument resolvers.
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
* @param mavContainer the ModelAndViewContainer for this 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
|
||||||
* @return the raw value returned by the invoked method
|
* @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... providedArgs) throws Exception {
|
||||||
|
|
||||||
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
|
Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
|
||||||
|
|
@ -129,7 +134,7 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
sb.append(Arrays.asList(args));
|
sb.append(Arrays.asList(args));
|
||||||
logger.trace(sb.toString());
|
logger.trace(sb.toString());
|
||||||
}
|
}
|
||||||
Object returnValue = invoke(args);
|
Object returnValue = doInvoke(args);
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
|
logger.trace("Method [" + getMethod().getName() + "] returned [" + returnValue + "]");
|
||||||
}
|
}
|
||||||
|
|
@ -206,10 +211,11 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoke the handler method with the given argument values.
|
* 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());
|
ReflectionUtils.makeAccessible(getBridgedMethod());
|
||||||
try {
|
try {
|
||||||
return getBridgedMethod().invoke(getBean(), args);
|
return getBridgedMethod().invoke(getBean(), args);
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register {@link HandlerMethodReturnValueHandler} instances to use to
|
* Register {@link HandlerMethodReturnValueHandler} instances to use to
|
||||||
* handle return values.
|
* handle return values.
|
||||||
|
|
@ -99,16 +100,14 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
/**
|
/**
|
||||||
* Invokes the method and handles the return value through one of the
|
* Invokes the method and handles the return value through one of the
|
||||||
* configured {@link HandlerMethodReturnValueHandler}s.
|
* configured {@link HandlerMethodReturnValueHandler}s.
|
||||||
*
|
|
||||||
* @param webRequest the current request
|
* @param webRequest the current request
|
||||||
* @param mavContainer the ModelAndViewContainer for this 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 {
|
ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {
|
||||||
|
|
||||||
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
|
Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
|
||||||
|
|
||||||
setResponseStatus(webRequest);
|
setResponseStatus(webRequest);
|
||||||
|
|
||||||
if (returnValue == null) {
|
if (returnValue == null) {
|
||||||
|
|
@ -123,9 +122,9 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
}
|
}
|
||||||
|
|
||||||
mavContainer.setRequestHandled(false);
|
mavContainer.setRequestHandled(false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
|
this.returnValueHandlers.handleReturnValue(
|
||||||
|
returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
if (logger.isTraceEnabled()) {
|
if (logger.isTraceEnabled()) {
|
||||||
|
|
@ -165,20 +164,20 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
* Does this method have the response status instruction?
|
* Does this method have the response status instruction?
|
||||||
*/
|
*/
|
||||||
private boolean hasResponseStatus() {
|
private boolean hasResponseStatus() {
|
||||||
return this.responseStatus != null;
|
return (this.responseStatus != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getReturnValueHandlingErrorMessage(String message, Object returnValue) {
|
private String getReturnValueHandlingErrorMessage(String message, Object returnValue) {
|
||||||
StringBuilder sb = new StringBuilder(message);
|
StringBuilder sb = new StringBuilder(message);
|
||||||
if (returnValue != null) {
|
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());
|
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
|
* the given value (or raises an Exception if the value is one) rather than
|
||||||
* actually invoking the controller method. This is useful when processing
|
* actually invoking the controller method. This is useful when processing
|
||||||
* async return values (e.g. Callable, DeferredResult, ListenableFuture).
|
* 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
|
* simple {@link Callable} instead of the original controller as the handler in
|
||||||
* order to return the fixed (concurrent) result value given to it. Effectively
|
* order to return the fixed (concurrent) result value given to it. Effectively
|
||||||
* "resumes" processing with the asynchronously produced return value.
|
* "resumes" processing with the asynchronously produced return value.
|
||||||
|
|
@ -198,7 +197,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
|
|
||||||
private final MethodParameter returnType;
|
private final MethodParameter returnType;
|
||||||
|
|
||||||
|
|
||||||
public ConcurrentResultHandlerMethod(final Object result, ConcurrentResultMethodParameter returnType) {
|
public ConcurrentResultHandlerMethod(final Object result, ConcurrentResultMethodParameter returnType) {
|
||||||
super(new Callable<Object>() {
|
super(new Callable<Object>() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -242,8 +240,9 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MethodParameter sub-class based on the actual return value type or if
|
* MethodParameter subclass based on the actual return value type or if
|
||||||
* that's null falling back on the generic type within the declared async
|
* that's null falling back on the generic type within the declared async
|
||||||
* return type, e.g. Foo instead of {@code DeferredResult<Foo>}.
|
* return type, e.g. Foo instead of {@code DeferredResult<Foo>}.
|
||||||
*/
|
*/
|
||||||
|
|
@ -253,7 +252,6 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
|
|
||||||
private final ResolvableType returnType;
|
private final ResolvableType returnType;
|
||||||
|
|
||||||
|
|
||||||
public ConcurrentResultMethodParameter(Object returnValue) {
|
public ConcurrentResultMethodParameter(Object returnValue) {
|
||||||
super(-1);
|
super(-1);
|
||||||
this.returnValue = returnValue;
|
this.returnValue = returnValue;
|
||||||
|
|
@ -262,7 +260,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getParameterType() {
|
public Class<?> getParameterType() {
|
||||||
return (returnValue != null ? returnValue.getClass() : this.returnType.getRawClass());
|
return (this.returnValue != null ? this.returnValue.getClass() : this.returnType.getRawClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue