
cc.shacocloud.mirage.restful.HandlerMethod Maven / Gradle / Ivy
package cc.shacocloud.mirage.restful;
import cc.shacocloud.mirage.bean.BeanFactory;
import cc.shacocloud.mirage.utils.ClassUtil;
import cc.shacocloud.mirage.utils.MethodParameter;
import cc.shacocloud.mirage.utils.ResolvableType;
import cc.shacocloud.mirage.utils.Utils;
import cc.shacocloud.mirage.utils.annotation.AnnotatedElementUtils;
import cc.shacocloud.mirage.utils.charSequence.StrUtil;
import cc.shacocloud.mirage.utils.collection.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* 封装处理程序的方法和相关信息,提供了方法参数,方法返回值,方法注解等方便
*/
public class HandlerMethod {
@Nullable
protected final BeanFactory beanFactory;
private final Object bean;
private final Class> beanType;
private final Method method;
private final String description;
protected MethodParameter[] parameters;
@Nullable
private HandlerMethod resolvedFromHandlerMethod;
@Nullable
private volatile List interfaceParameterAnnotations;
/**
* 从bean实例和方法创建实例
*/
public HandlerMethod(@NotNull Object bean, @NotNull Method method) {
this.bean = bean;
this.beanFactory = null;
this.beanType = bean.getClass();
this.method = method;
this.parameters = initMethodParameters();
this.description = Utils.methodDescription(this.beanType, this.method);
}
/**
* 从Bean实例,方法名称和参数类型创建实例。
*
* @throws NoSuchMethodException 当找不到方法时抛出该例外
*/
public HandlerMethod(@NotNull Object bean, @NotNull String methodName, Class>... parameterTypes) throws NoSuchMethodException {
this.bean = bean;
this.beanFactory = null;
this.beanType = bean.getClass();
this.method = bean.getClass().getMethod(methodName, parameterTypes);
this.parameters = initMethodParameters();
this.description = Utils.methodDescription(this.beanType, this.method);
}
/**
* 从一个bean名,方法,以及创建一个实例的BeanFactory
* 该方法 {@link #createWithResolvedBean()} 可以随后用于重新创建{@link HandlerMethod}与初始化的 bean
*/
public HandlerMethod(@NotNull String beanName, @NotNull BeanFactory beanFactory, @NotNull Method method) {
this.bean = beanName;
this.beanFactory = beanFactory;
this.beanType = beanFactory.getBeanType(beanName);
this.method = method;
this.parameters = initMethodParameters();
this.description = Utils.methodDescription(this.beanType, this.method);
}
/**
* 复制用于子类的构造函数
*/
protected HandlerMethod(@NotNull HandlerMethod handlerMethod) {
this.bean = handlerMethod.bean;
this.beanFactory = handlerMethod.beanFactory;
this.beanType = handlerMethod.beanType;
this.method = handlerMethod.method;
this.parameters = handlerMethod.parameters;
this.description = handlerMethod.description;
this.resolvedFromHandlerMethod = handlerMethod.resolvedFromHandlerMethod;
}
/**
* 使用解析后的处理程序重新创建HandlerMethod
*/
private HandlerMethod(@NotNull HandlerMethod handlerMethod, Object handler) {
this.bean = handler;
this.beanFactory = handlerMethod.beanFactory;
this.beanType = handlerMethod.beanType;
this.method = handlerMethod.method;
this.parameters = handlerMethod.parameters;
this.resolvedFromHandlerMethod = handlerMethod;
this.description = handlerMethod.description;
}
protected MethodParameter[] initMethodParameters() {
int count = this.method.getParameterCount();
MethodParameter[] result = new MethodParameter[count];
for (int i = 0; i < count; i++) {
result[i] = buildMethodParameter(i);
}
return result;
}
/**
* 构建方法指定索引值的参数,下标从 0 开始,一般来说值为 -1 的为方法的返回值类型
*/
protected MethodParameter buildMethodParameter(int index) {
return new HandlerMethodParameter(this, index);
}
/**
* 返回此处理程序方法的bean
*/
public Object getBean() {
return this.bean;
}
/**
* 返回此处理程序方法的方法
*/
public Method getMethod() {
return this.method;
}
/**
* 此方法返回的处理程序,该处理方法的类型。
*/
public Class> getBeanType() {
return this.beanType;
}
/**
* 返回此处理程序方法的方法参数
*/
public MethodParameter[] getMethodParameters() {
return this.parameters;
}
/**
* 返回HandlerMethod返回类型
*/
public MethodParameter getReturnType() {
return buildMethodParameter(-1);
}
/**
* 返回实际的返回值类型
*/
public MethodParameter getReturnValueType(@Nullable Object returnValue) {
return new ReturnValueMethodParameter(this, returnValue);
}
/**
* 如果该方法返回类型为void返回true 否则为false。
*/
public boolean isVoid() {
return Void.TYPE.equals(getReturnType().getParameterType());
}
/**
* @see AnnotatedElementUtils#getAnnotation
*/
@Nullable
public A getMethodAnnotation(Class annotationType) {
return AnnotatedElementUtils.getAnnotation(this.method, annotationType);
}
/**
* @see AnnotatedElementUtils#hasAnnotation
*/
public boolean hasMethodAnnotation(Class annotationType) {
return AnnotatedElementUtils.hasAnnotation(this.method, annotationType);
}
/**
* 返回从{@link HandlerMethod}解析得到的 {@link #createWithResolvedBean()}.
*/
@Nullable
public HandlerMethod getResolvedFromHandlerMethod() {
return this.resolvedFromHandlerMethod;
}
/**
* 如果所提供的实例包含一个bean的名称,而不是一个对象实例,一个bean之前,名称解析{@link HandlerMethod}创建并返回
*/
public HandlerMethod createWithResolvedBean() {
Object handler = this.bean;
if (handler instanceof String) {
Objects.requireNonNull(this.beanFactory, "没有BeanFactory无法解析Bean名称");
handler = this.beanFactory.getBean((String) handler);
}
return new HandlerMethod(this, handler);
}
/**
* 返回此处理程序方法的简短表示形式,以用于日志消息。
*/
public String getShortLogMessage() {
return getBeanType().getName() + "#" + this.method.getName() +
"[" + this.method.getParameterCount() + " args]";
}
public List getInterfaceParameterAnnotations() {
List parameterAnnotations = this.interfaceParameterAnnotations;
if (parameterAnnotations == null) {
parameterAnnotations = new ArrayList<>();
for (Class> ifc : ClassUtil.getAllInterfacesForClassAsSet(this.method.getDeclaringClass())) {
for (Method candidate : ifc.getMethods()) {
if (isOverrideFor(candidate)) {
parameterAnnotations.add(candidate.getParameterAnnotations());
}
}
}
this.interfaceParameterAnnotations = parameterAnnotations;
}
return parameterAnnotations;
}
private boolean isOverrideFor(@NotNull Method candidate) {
if (!candidate.getName().equals(this.method.getName()) ||
candidate.getParameterCount() != this.method.getParameterCount()) {
return false;
}
Class>[] paramTypes = this.method.getParameterTypes();
if (Arrays.equals(candidate.getParameterTypes(), paramTypes)) {
return true;
}
for (int i = 0; i < paramTypes.length; i++) {
if (paramTypes[i] != ResolvableType.forMethodParameter(candidate, i, this.method.getDeclaringClass()).resolve()) {
return false;
}
}
return true;
}
@Override
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}
if (!(other instanceof HandlerMethod)) {
return false;
}
HandlerMethod otherMethod = (HandlerMethod) other;
return (this.bean.equals(otherMethod.bean) && this.method.equals(otherMethod.method));
}
@Override
public int hashCode() {
return (this.bean.hashCode() * 31 + this.method.hashCode());
}
/**
* 获取处理器方法描述
*/
public String getDescription() {
return description;
}
@Override
public String toString() {
return getDescription();
}
// ------------------------ InvocableHandlerMethod 支持的方法
@Nullable
protected Object findProvidedArgument(MethodParameter parameter, @Nullable Object... providedArgs) {
if (ArrayUtil.isNotEmpty(providedArgs)) {
for (Object providedArg : providedArgs) {
if (parameter.getParameterType().isInstance(providedArg)) {
return providedArg;
}
}
}
return null;
}
protected String formatArgumentError(@NotNull MethodParameter param, String message) {
return "无法解析方法 '" + Utils.methodDescription(param.getDeclaringClass(), Objects.requireNonNull(param.getMethod()))
+ "' 参数索引[" + param.getParameterIndex() + "] 类型[" + param.getParameterType() + "]"
+ (StrUtil.isNotBlank(message) ? (": " + message) : "");
}
/**
* 断言目标bean类是在给定的方法被声明的类的实例
*/
protected void assertTargetBean(@NotNull Method method, @NotNull Object targetBean, Object[] args) {
Class> methodDeclaringClass = method.getDeclaringClass();
Class> targetBeanClass = targetBean.getClass();
if (!methodDeclaringClass.isAssignableFrom(targetBeanClass)) {
String text = "映射的处理程序方法类 '" + methodDeclaringClass.getName() + "' 不是实际控制器bean类的实例 '" +
targetBeanClass.getName() + "'。 如果控制器需要代理 (e.g. due to @Transactional),请使用基于代理的类。";
throw new IllegalStateException(formatInvokeError(text, args));
}
}
protected String formatInvokeError(String text, Object @NotNull [] args) {
String formattedArgs = IntStream.range(0, args.length)
.mapToObj(i -> (args[i] != null ?
"下标[" + i + "] [目标类型=" + args[i].getClass().getName() + "] [值=" + args[i] + "]" :
"下标[" + i + "] [null]"))
.collect(Collectors.joining(",\n", " ", " "));
return text + "\n" +
"控制器 [" + getBeanType().getName() + "]\n" +
"方法 [" + getMethod().toGenericString() + "] \n" +
"参数:\n" + formattedArgs;
}
/**
* 具有 HandlerMethod 特定行为的 MethodParameter
*/
public static class HandlerMethodParameter extends MethodParameter {
private final HandlerMethod handlerMethod;
@Nullable
private volatile Annotation[] combinedAnnotations;
public HandlerMethodParameter(@NotNull HandlerMethod handlerMethod, int index) {
super(handlerMethod.method, index);
this.handlerMethod = handlerMethod;
}
public HandlerMethodParameter(HandlerMethodParameter original) {
super(original);
this.handlerMethod = original.handlerMethod;
}
@NotNull
@Override
public Class> getContainingClass() {
return handlerMethod.getBeanType();
}
@Override
public T getMethodAnnotation(@NotNull Class annotationType) {
return handlerMethod.getMethodAnnotation(annotationType);
}
@Override
public boolean hasMethodAnnotation(@NotNull Class annotationType) {
return handlerMethod.hasMethodAnnotation(annotationType);
}
@NotNull
@Override
public Annotation[] getParameterAnnotations() {
Annotation[] anns = this.combinedAnnotations;
if (anns == null) {
anns = super.getParameterAnnotations();
int index = getParameterIndex();
if (index >= 0) {
for (Annotation[][] ifcAnns : handlerMethod.getInterfaceParameterAnnotations()) {
if (index < ifcAnns.length) {
Annotation[] paramAnns = ifcAnns[index];
if (paramAnns.length > 0) {
List merged = new ArrayList<>(anns.length + paramAnns.length);
merged.addAll(Arrays.asList(anns));
for (Annotation paramAnn : paramAnns) {
boolean existingType = false;
for (Annotation ann : anns) {
if (ann.annotationType() == paramAnn.annotationType()) {
existingType = true;
break;
}
}
if (!existingType) {
merged.add(adaptAnnotation(paramAnn));
}
}
anns = merged.toArray(new Annotation[0]);
}
}
}
}
this.combinedAnnotations = anns;
}
return anns;
}
@NotNull
@Override
public HandlerMethodParameter clone() {
return new HandlerMethodParameter(this);
}
}
/**
* 基于实际返回值的HandlerMethod返回类型的MethodParameter
*/
private static class ReturnValueMethodParameter extends HandlerMethodParameter {
@Nullable
private final Object returnValue;
public ReturnValueMethodParameter(HandlerMethod handlerMethod, @Nullable Object returnValue) {
super(handlerMethod, -1);
this.returnValue = returnValue;
}
protected ReturnValueMethodParameter(ReturnValueMethodParameter original) {
super(original);
this.returnValue = original.returnValue;
}
@Override
public Class> getParameterType() {
return (this.returnValue != null ? this.returnValue.getClass() : super.getParameterType());
}
@Override
public @NotNull ReturnValueMethodParameter clone() {
return new ReturnValueMethodParameter(this);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy