mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-05-09 23:51:34 +08:00
add AnnotationProxy
This commit is contained in:
parent
bfac3a54df
commit
ccc9f2568f
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
### 🐣新特性
|
### 🐣新特性
|
||||||
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@gitee)
|
* 【http 】 HttpRequest.form采用TableMap方式(issue#I4W427@gitee)
|
||||||
|
* 【core 】 AnnotationUtil增加getAnnotationAlias方法(pr#554@gitee)
|
||||||
### 🐞Bug修复
|
### 🐞Bug修复
|
||||||
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@gitee)
|
* 【core 】 修复ObjectUtil.hasNull传入null返回true的问题(pr#555@gitee)
|
||||||
|
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
package cn.hutool.core.annotation;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.reflect.InvocationHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注解代理<br>
|
||||||
|
* 通过代理指定注解,可以自定义调用注解的方法逻辑,如支持{@link Alias} 注解
|
||||||
|
*
|
||||||
|
* @param <T> 注解类型
|
||||||
|
* @since 5.7.23
|
||||||
|
*/
|
||||||
|
public class AnnotationProxy<T extends Annotation> implements Annotation, InvocationHandler, Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private final T annotation;
|
||||||
|
private final Class<T> type;
|
||||||
|
private final Map<String, Object> attributes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构造
|
||||||
|
*
|
||||||
|
* @param annotation 注解
|
||||||
|
*/
|
||||||
|
public AnnotationProxy(T annotation) {
|
||||||
|
this.annotation = annotation;
|
||||||
|
//noinspection unchecked
|
||||||
|
this.type = (Class<T>) annotation.annotationType();
|
||||||
|
this.attributes = initAttributes();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<? extends Annotation> annotationType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||||
|
|
||||||
|
// 注解别名
|
||||||
|
Alias alias = method.getAnnotation(Alias.class);
|
||||||
|
if(null != alias){
|
||||||
|
final String name = alias.value();
|
||||||
|
if(StrUtil.isNotBlank(name)){
|
||||||
|
if(false == attributes.containsKey(name)){
|
||||||
|
throw new IllegalArgumentException(StrUtil.format("No method for alias: [{}]", name));
|
||||||
|
}
|
||||||
|
return attributes.get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object value = attributes.get(method.getName());
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return method.invoke(this, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化注解的属性<br>
|
||||||
|
* 此方法预先调用所有注解的方法,将注解方法值缓存于attributes中
|
||||||
|
*
|
||||||
|
* @return 属性(方法结果)映射
|
||||||
|
*/
|
||||||
|
private Map<String, Object> initAttributes() {
|
||||||
|
final Method[] methods = ReflectUtil.getMethods(this.type);
|
||||||
|
final Map<String, Object> attributes = new HashMap<>(methods.length, 1);
|
||||||
|
|
||||||
|
for (Method method : methods) {
|
||||||
|
// 跳过匿名内部类自动生成的方法
|
||||||
|
if (method.isSynthetic()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
attributes.put(method.getName(), ReflectUtil.invoke(this.annotation, method));
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
}
|
@ -2,11 +2,15 @@ package cn.hutool.core.annotation;
|
|||||||
|
|
||||||
import cn.hutool.core.exceptions.UtilException;
|
import cn.hutool.core.exceptions.UtilException;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
import java.lang.annotation.Annotation;
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Inherited;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
import java.lang.reflect.AnnotatedElement;
|
import java.lang.reflect.AnnotatedElement;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
@ -219,18 +223,11 @@ public class AnnotationUtil {
|
|||||||
* @param annotationType 注解类型Class
|
* @param annotationType 注解类型Class
|
||||||
* @param <T> 注解类型
|
* @param <T> 注解类型
|
||||||
* @return 别名支持后的注解
|
* @return 别名支持后的注解
|
||||||
|
* @since 5.7.23
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T extends Annotation> T getAnnotationAlias(AnnotatedElement annotationEle, Class<T> annotationType) {
|
public static <T extends Annotation> T getAnnotationAlias(AnnotatedElement annotationEle, Class<T> annotationType) {
|
||||||
T annotation = getAnnotation(annotationEle, annotationType);
|
final T annotation = getAnnotation(annotationEle, annotationType);
|
||||||
Object o = Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{annotationType}, (proxy, method, args) -> {
|
return (T) Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{annotationType}, new AnnotationProxy<>(annotation));
|
||||||
Alias alias = method.getAnnotation(Alias.class);
|
|
||||||
if (ObjectUtil.isNotNull(alias) && StrUtil.isNotBlank(alias.value())) {
|
|
||||||
Method aliasMethod = annotationType.getMethod(alias.value());
|
|
||||||
return ReflectUtil.invoke(annotation, aliasMethod);
|
|
||||||
}
|
|
||||||
return method.invoke(args);
|
|
||||||
});
|
|
||||||
return (T) o;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,8 @@ public class ReflectUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得指定类过滤后的Public方法列表
|
* 获得指定类过滤后的Public方法列表<br>
|
||||||
|
* TODO 6.x此方法更改返回Method[]
|
||||||
*
|
*
|
||||||
* @param clazz 查找方法的类
|
* @param clazz 查找方法的类
|
||||||
* @param filter 过滤器
|
* @param filter 过滤器
|
||||||
|
Loading…
x
Reference in New Issue
Block a user