mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add methods and comment
This commit is contained in:
parent
c27c74f192
commit
4e5cc6c5d0
@ -3,6 +3,7 @@ package cn.hutool.core.annotation;
|
||||
import cn.hutool.core.annotation.scanner.*;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.exceptions.UtilException;
|
||||
import cn.hutool.core.lang.Opt;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
@ -315,104 +316,19 @@ public class AnnotationUtil {
|
||||
return annotationType.isAnnotationPresent(Inherited.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置新的注解的属性(字段)值
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @param annotationField 注解属性(字段)名称
|
||||
* @param value 要更新的属性值
|
||||
* @since 5.5.2
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static void setValue(Annotation annotation, String annotationField, Object value) {
|
||||
final Map memberValues = (Map) ReflectUtil.getFieldValue(Proxy.getInvocationHandler(annotation), "memberValues");
|
||||
memberValues.put(annotationField, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取别名支持后的注解
|
||||
*
|
||||
* @param annotationEle 被注解的类
|
||||
* @param annotationType 注解类型Class
|
||||
* @param <T> 注解类型
|
||||
* @return 别名支持后的注解
|
||||
* @since 5.7.23
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Annotation> T getAnnotationAlias(AnnotatedElement annotationEle, Class<T> annotationType) {
|
||||
final T annotation = getAnnotation(annotationEle, annotationType);
|
||||
return (T) Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{annotationType}, new AnnotationProxy<>(annotation));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定注解实例与其元注解转为合成注解
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @param annotationType 注解类
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> T getSynthesizedAnnotation(Annotation annotation, Class<T> annotationType) {
|
||||
// TODO 缓存合成注解信息,避免重复解析
|
||||
return aggregatingFromAnnotationWithMeta(annotation).synthesize(annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取元素上距离指定元素最接近的合成注解
|
||||
* <ul>
|
||||
* <li>若元素是类,则递归解析全部父类和全部父接口上的注解;</li>
|
||||
* <li>若元素是方法、属性或注解,则只解析其直接声明的注解;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
|
||||
* @param annotationType 注解类
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> T getSynthesizedAnnotation(AnnotatedElement annotatedEle, Class<T> annotationType) {
|
||||
T target = annotatedEle.getAnnotation(annotationType);
|
||||
if (ObjectUtil.isNotNull(target)) {
|
||||
return target;
|
||||
}
|
||||
AnnotationScanner[] scanners = new AnnotationScanner[]{
|
||||
new MetaAnnotationScanner(), new TypeAnnotationScanner(), new MethodAnnotationScanner(), new FieldAnnotationScanner()
|
||||
};
|
||||
return AnnotationScanner.scanByAnySupported(annotatedEle, scanners).stream()
|
||||
.map(annotation -> getSynthesizedAnnotation(annotation, annotationType))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取元素上所有指定注解
|
||||
* <ul>
|
||||
* <li>若元素是类,则递归解析全部父类和全部父接口上的注解;</li>
|
||||
* <li>若元素是方法、属性或注解,则只解析其直接声明的注解;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
|
||||
* @param annotationType 注解类
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> List<T> getAllSynthesizedAnnotations(AnnotatedElement annotatedEle, Class<T> annotationType) {
|
||||
AnnotationScanner[] scanners = new AnnotationScanner[]{
|
||||
new MetaAnnotationScanner(), new TypeAnnotationScanner(), new MethodAnnotationScanner(), new FieldAnnotationScanner()
|
||||
};
|
||||
return AnnotationScanner.scanByAnySupported(annotatedEle, scanners).stream()
|
||||
.map(annotation -> getSynthesizedAnnotation(annotation, annotationType))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描注解类,以及注解类的{@link Class}层级结构中的注解,将返回除了{@link #META_ANNOTATIONS}中指定的JDK默认注解外,
|
||||
* 按元注解对象与{@code annotationType}的距离和{@link Class#getAnnotations()}顺序排序的注解对象集合
|
||||
*
|
||||
* <p>比如:<br>
|
||||
* 若{@code annotationType}为 A,且A存在元注解B,B又存在元注解C和D,则有:
|
||||
* <pre>
|
||||
* |-> C.class [@a, @b]
|
||||
* A.class -> B.class [@a] -|
|
||||
* |-> D.class [@a, @c]
|
||||
* </pre>
|
||||
* 扫描A,则该方法最终将返回 {@code [@a, @a, @b, @a, @c]}
|
||||
*
|
||||
* @param annotationType 注解类
|
||||
* @return 注解对象集合
|
||||
* @see MetaAnnotationScanner
|
||||
@ -432,6 +348,16 @@ public class AnnotationUtil {
|
||||
* </ul>
|
||||
* 注解根据其声明类/接口被扫描的顺序排序,若注解都在同一个{@link Class}中被声明,则还会遵循{@link Class#getAnnotations()}的顺序。
|
||||
*
|
||||
* <p>比如:<br>
|
||||
* 若{@code targetClass}为{@code A.class},且{@code A.class}存在父类{@code B.class}、父接口{@code C.class},
|
||||
* 三个类的注解声明情况如下:
|
||||
* <pre>
|
||||
* |-> B.class [@a, @b]
|
||||
* A.class [@a] -|
|
||||
* |-> C.class [@a, @c]
|
||||
* </pre>
|
||||
* 则该方法最终将返回 {@code [@a, @a, @b, @a, @c]}
|
||||
*
|
||||
* @param targetClass 类
|
||||
* @return 注解对象集合
|
||||
* @see TypeAnnotationScanner
|
||||
@ -452,6 +378,14 @@ public class AnnotationUtil {
|
||||
* </ul>
|
||||
* 方法上的注解根据方法的声明类/接口被扫描的顺序排序,若注解都在同一个类的同一个方法中被声明,则还会遵循{@link Method#getAnnotations()}的顺序。
|
||||
*
|
||||
* <p>比如:<br>
|
||||
* 若方法X声明于{@code A.class},且重载/重写自父类{@code B.class},并且父类中的方法X由重写至其实现的接口{@code C.class},
|
||||
* 三个类的注解声明情况如下:
|
||||
* <pre>
|
||||
* A#X()[@a] -> B#X()[@b] -> C#X()[@c]
|
||||
* </pre>
|
||||
* 则该方法最终将返回 {@code [@a, @b, @c]}
|
||||
*
|
||||
* @param method 方法
|
||||
* @return 注解对象集合
|
||||
* @see MethodAnnotationScanner
|
||||
@ -460,6 +394,152 @@ public class AnnotationUtil {
|
||||
return new MethodAnnotationScanner(true).getIfSupport(method);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置新的注解的属性(字段)值
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @param annotationField 注解属性(字段)名称
|
||||
* @param value 要更新的属性值
|
||||
* @since 5.5.2
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static void setValue(Annotation annotation, String annotationField, Object value) {
|
||||
final Map memberValues = (Map) ReflectUtil.getFieldValue(Proxy.getInvocationHandler(annotation), "memberValues");
|
||||
memberValues.put(annotationField, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 该注解对象是否为通过代理类生成的合成注解
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @return 是否
|
||||
* @see SynthesizedAnnotationProxy#isProxyAnnotation(Class)
|
||||
*/
|
||||
public static boolean isSynthesizedAnnotation(Annotation annotation) {
|
||||
return SynthesizedAnnotationProxy.isProxyAnnotation(annotation.getClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取别名支持后的注解
|
||||
*
|
||||
* @param annotationEle 被注解的类
|
||||
* @param annotationType 注解类型Class
|
||||
* @param <T> 注解类型
|
||||
* @return 别名支持后的注解
|
||||
* @since 5.7.23
|
||||
*/
|
||||
public static <T extends Annotation> T getAnnotationAlias(AnnotatedElement annotationEle, Class<T> annotationType) {
|
||||
final T annotation = getAnnotation(annotationEle, annotationType);
|
||||
return aggregatingFromAnnotation(annotation).synthesize(annotationType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将指定注解实例与其元注解转为合成注解
|
||||
*
|
||||
* @param annotationType 注解类
|
||||
* @param annotations 注解对象
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> T getSynthesizedAnnotation(Class<T> annotationType, Annotation... annotations) {
|
||||
// TODO 缓存合成注解信息,避免重复解析
|
||||
return Opt.ofNullable(annotations)
|
||||
.filter(ArrayUtil::isNotEmpty)
|
||||
.map(AnnotationUtil::aggregatingFromAnnotationWithMeta)
|
||||
.map(a -> a.synthesize(annotationType))
|
||||
.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>获取元素上距离指定元素最接近的合成注解
|
||||
* <ul>
|
||||
* <li>若元素是类,则递归解析全部父类和全部父接口上的注解;</li>
|
||||
* <li>若元素是方法、属性或注解,则只解析其直接声明的注解;</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>注解合成规则如下:
|
||||
* 若{@code AnnotatedEle}按顺序从上到下声明了A,B,C三个注解,且三注解存在元注解如下:
|
||||
* <pre>
|
||||
* A -> MA1 -> MA2
|
||||
* B -> MB1 -> MB2
|
||||
* C -> MC1
|
||||
* </pre>
|
||||
* 此时入参{@code annotationType}类型为{@code MB1},则最终将优先返回基于根注解B合成的合成注解
|
||||
*
|
||||
* @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
|
||||
* @param annotationType 注解类
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> T getSynthesizedAnnotation(AnnotatedElement annotatedEle, Class<T> annotationType) {
|
||||
T target = annotatedEle.getAnnotation(annotationType);
|
||||
if (ObjectUtil.isNotNull(target)) {
|
||||
return target;
|
||||
}
|
||||
AnnotationScanner[] scanners = new AnnotationScanner[]{
|
||||
new MetaAnnotationScanner(), new TypeAnnotationScanner(), new MethodAnnotationScanner(), new FieldAnnotationScanner()
|
||||
};
|
||||
return AnnotationScanner.scanByAnySupported(annotatedEle, scanners).stream()
|
||||
.map(annotation -> getSynthesizedAnnotation(annotationType, annotation))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取元素上所有指定注解
|
||||
* <ul>
|
||||
* <li>若元素是类,则递归解析全部父类和全部父接口上的注解;</li>
|
||||
* <li>若元素是方法、属性或注解,则只解析其直接声明的注解;</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>注解合成规则如下:
|
||||
* 若{@code AnnotatedEle}按顺序从上到下声明了A,B,C三个注解,且三注解存在元注解如下:
|
||||
* <pre>
|
||||
* A -> M1 -> M2
|
||||
* B -> M3 -> M1
|
||||
* C -> M2
|
||||
* </pre>
|
||||
* 此时入参{@code annotationType}类型为{@code M1},则最终将返回基于根注解A与根注解B合成的合成注解。
|
||||
*
|
||||
* @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission
|
||||
* @param annotationType 注解类
|
||||
* @param <T> 注解类型
|
||||
* @return 合成注解
|
||||
* @see SynthesizedAggregateAnnotation
|
||||
*/
|
||||
public static <T extends Annotation> List<T> getAllSynthesizedAnnotations(AnnotatedElement annotatedEle, Class<T> annotationType) {
|
||||
AnnotationScanner[] scanners = new AnnotationScanner[]{
|
||||
new MetaAnnotationScanner(), new TypeAnnotationScanner(), new MethodAnnotationScanner(), new FieldAnnotationScanner()
|
||||
};
|
||||
return AnnotationScanner.scanByAnySupported(annotatedEle, scanners).stream()
|
||||
.map(annotation -> getSynthesizedAnnotation(annotationType, annotation))
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象进行聚合
|
||||
*
|
||||
* @param annotations 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
public static SynthesizedAggregateAnnotation aggregatingFromAnnotation(Annotation... annotations) {
|
||||
return new GenericSynthesizedAggregateAnnotation(Arrays.asList(annotations), EmptyAnnotationScanner.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象及其元注解进行聚合
|
||||
*
|
||||
* @param annotations 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
public static SynthesizedAggregateAnnotation aggregatingFromAnnotationWithMeta(Annotation... annotations) {
|
||||
return new GenericSynthesizedAggregateAnnotation(Arrays.asList(annotations), new MetaAnnotationScanner());
|
||||
}
|
||||
|
||||
/**
|
||||
* 方法是否为注解属性方法。 <br>
|
||||
* 方法无参数,且有返回值的方法认为是注解属性的方法。
|
||||
@ -470,24 +550,4 @@ public class AnnotationUtil {
|
||||
return method.getParameterCount() == 0 && method.getReturnType() != void.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象进行聚合
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
static SynthesizedAggregateAnnotation aggregatingFromAnnotation(Annotation annotation) {
|
||||
return new GenericSynthesizedAggregateAnnotation(Collections.singletonList(annotation), EmptyAnnotationScanner.INSTANCE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 对指定注解对象及其元注解进行聚合
|
||||
*
|
||||
* @param annotation 注解对象
|
||||
* @return 聚合注解
|
||||
*/
|
||||
static SynthesizedAggregateAnnotation aggregatingFromAnnotationWithMeta(Annotation annotation) {
|
||||
return new GenericSynthesizedAggregateAnnotation(annotation);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import java.util.stream.Stream;
|
||||
* @param <T> 注解类型
|
||||
* @author huangchengxing
|
||||
*/
|
||||
public class GenericSynthesizedAnnotation<R, T extends Annotation> implements Annotation, SynthesizedAnnotation {
|
||||
public class GenericSynthesizedAnnotation<R, T extends Annotation> implements SynthesizedAnnotation {
|
||||
|
||||
private final R root;
|
||||
private final T annotation;
|
||||
|
Loading…
Reference in New Issue
Block a user