Increase sharing among InvocableHandlerMethod variants
In particular between reactive and non-reactive web variants, but also preparing for a messaing reactive variant.
This commit is contained in:
@@ -21,6 +21,8 @@ import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -36,6 +38,8 @@ import org.springframework.http.HttpStatus;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
|
||||
/**
|
||||
@@ -172,7 +176,6 @@ public class HandlerMethod {
|
||||
this.resolvedFromHandlerMethod = handlerMethod;
|
||||
}
|
||||
|
||||
|
||||
private MethodParameter[] initMethodParameters() {
|
||||
int count = this.bridgedMethod.getParameterCount();
|
||||
MethodParameter[] result = new MethodParameter[count];
|
||||
@@ -390,6 +393,57 @@ public class HandlerMethod {
|
||||
}
|
||||
|
||||
|
||||
// Support methods for use in "InvocableHandlerMethod" sub-class variants..
|
||||
|
||||
@Nullable
|
||||
protected static Object findProvidedArgument(MethodParameter parameter, @Nullable Object... providedArgs) {
|
||||
if (!ObjectUtils.isEmpty(providedArgs)) {
|
||||
for (Object providedArg : providedArgs) {
|
||||
if (parameter.getParameterType().isInstance(providedArg)) {
|
||||
return providedArg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static String formatArgumentError(MethodParameter param, String message) {
|
||||
return "Could not resolve parameter [" + param.getParameterIndex() + "] in " +
|
||||
param.getExecutable().toGenericString() + (StringUtils.hasText(message) ? ": " + message : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the target bean class is an instance of the class where the given
|
||||
* method is declared. In some cases the actual controller instance at request-
|
||||
* processing time may be a JDK dynamic proxy (lazy initialization, prototype
|
||||
* beans, and others). {@code @Controller}'s that require proxying should prefer
|
||||
* class-based proxy mechanisms.
|
||||
*/
|
||||
protected void assertTargetBean(Method method, Object targetBean, Object[] args) {
|
||||
Class<?> methodDeclaringClass = method.getDeclaringClass();
|
||||
Class<?> targetBeanClass = targetBean.getClass();
|
||||
if (!methodDeclaringClass.isAssignableFrom(targetBeanClass)) {
|
||||
String text = "The mapped handler method class '" + methodDeclaringClass.getName() +
|
||||
"' is not an instance of the actual controller bean class '" +
|
||||
targetBeanClass.getName() + "'. If the controller requires proxying " +
|
||||
"(e.g. due to @Transactional), please use class-based proxying.";
|
||||
throw new IllegalStateException(formatInvokeError(text, args));
|
||||
}
|
||||
}
|
||||
|
||||
protected String formatInvokeError(String text, Object[] args) {
|
||||
String formattedArgs = IntStream.range(0, args.length)
|
||||
.mapToObj(i -> (args[i] != null ?
|
||||
"[" + i + "] [type=" + args[i].getClass().getName() + "] [value=" + args[i] + "]" :
|
||||
"[" + i + "] [null]"))
|
||||
.collect(Collectors.joining(",\n", " ", " "));
|
||||
return text + "\n" +
|
||||
"Controller [" + getBeanType().getName() + "]\n" +
|
||||
"Method [" + getBridgedMethod().toGenericString() + "] " +
|
||||
"with argument values:\n" + formattedArgs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A MethodParameter with HandlerMethod-specific behavior.
|
||||
*/
|
||||
|
||||
@@ -19,8 +19,6 @@ package org.springframework.web.method.support;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.springframework.core.DefaultParameterNameDiscoverer;
|
||||
import org.springframework.core.MethodParameter;
|
||||
@@ -28,7 +26,6 @@ import org.springframework.core.ParameterNameDiscoverer;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.support.SessionStatus;
|
||||
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||
@@ -182,23 +179,6 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Object findProvidedArgument(MethodParameter parameter, @Nullable Object... providedArgs) {
|
||||
if (!ObjectUtils.isEmpty(providedArgs)) {
|
||||
for (Object providedArg : providedArgs) {
|
||||
if (parameter.getParameterType().isInstance(providedArg)) {
|
||||
return providedArg;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String formatArgumentError(MethodParameter param, String message) {
|
||||
return "Could not resolve parameter [" + param.getParameterIndex() + "] in " +
|
||||
param.getExecutable().toGenericString() + (StringUtils.hasText(message) ? ": " + message : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke the handler method with the given argument values.
|
||||
*/
|
||||
@@ -231,37 +211,4 @@ public class InvocableHandlerMethod extends HandlerMethod {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assert that the target bean class is an instance of the class where the given
|
||||
* method is declared. In some cases the actual controller instance at request-
|
||||
* processing time may be a JDK dynamic proxy (lazy initialization, prototype
|
||||
* beans, and others). {@code @Controller}'s that require proxying should prefer
|
||||
* class-based proxy mechanisms.
|
||||
*/
|
||||
private void assertTargetBean(Method method, Object targetBean, Object[] args) {
|
||||
Class<?> methodDeclaringClass = method.getDeclaringClass();
|
||||
Class<?> targetBeanClass = targetBean.getClass();
|
||||
if (!methodDeclaringClass.isAssignableFrom(targetBeanClass)) {
|
||||
String text = "The mapped handler method class '" + methodDeclaringClass.getName() +
|
||||
"' is not an instance of the actual controller bean class '" +
|
||||
targetBeanClass.getName() + "'. If the controller requires proxying " +
|
||||
"(e.g. due to @Transactional), please use class-based proxying.";
|
||||
throw new IllegalStateException(formatInvokeError(text, args));
|
||||
}
|
||||
}
|
||||
|
||||
private String formatInvokeError(String text, Object[] args) {
|
||||
|
||||
String formattedArgs = IntStream.range(0, args.length)
|
||||
.mapToObj(i -> (args[i] != null ?
|
||||
"[" + i + "] [type=" + args[i].getClass().getName() + "] [value=" + args[i] + "]" :
|
||||
"[" + i + "] [null]"))
|
||||
.collect(Collectors.joining(",\n", " ", " "));
|
||||
|
||||
return text + "\n" +
|
||||
"Controller [" + getBeanType().getName() + "]\n" +
|
||||
"Method [" + getBridgedMethod().toGenericString() + "] " +
|
||||
"with argument values:\n" + formattedArgs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user