From 4e5cc6c5d0f879c6d0aecadec786f14e1a1e9b0b Mon Sep 17 00:00:00 2001 From: huangchengxing <841396397@qq.com> Date: Sat, 16 Jul 2022 18:37:33 +0800 Subject: [PATCH] add methods and comment --- .../core/annotation/AnnotationUtil.java | 288 +++++++++++------- .../GenericSynthesizedAnnotation.java | 2 +- 2 files changed, 175 insertions(+), 115 deletions(-) diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java index 271fc9e8a..0c3e70e1a 100755 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -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 注解类型 - * @return 别名支持后的注解 - * @since 5.7.23 - */ - @SuppressWarnings("unchecked") - public static T getAnnotationAlias(AnnotatedElement annotationEle, Class annotationType) { - final T annotation = getAnnotation(annotationEle, annotationType); - return (T) Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{annotationType}, new AnnotationProxy<>(annotation)); - } - - /** - * 将指定注解实例与其元注解转为合成注解 - * - * @param annotation 注解对象 - * @param annotationType 注解类 - * @param 注解类型 - * @return 合成注解 - * @see SynthesizedAggregateAnnotation - */ - public static T getSynthesizedAnnotation(Annotation annotation, Class annotationType) { - // TODO 缓存合成注解信息,避免重复解析 - return aggregatingFromAnnotationWithMeta(annotation).synthesize(annotationType); - } - - /** - * 获取元素上距离指定元素最接近的合成注解 - *
    - *
  • 若元素是类,则递归解析全部父类和全部父接口上的注解;
  • - *
  • 若元素是方法、属性或注解,则只解析其直接声明的注解;
  • - *
- * - * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission - * @param annotationType 注解类 - * @param 注解类型 - * @return 合成注解 - * @see SynthesizedAggregateAnnotation - */ - public static T getSynthesizedAnnotation(AnnotatedElement annotatedEle, Class 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); - } - - /** - * 获取元素上所有指定注解 - *
    - *
  • 若元素是类,则递归解析全部父类和全部父接口上的注解;
  • - *
  • 若元素是方法、属性或注解,则只解析其直接声明的注解;
  • - *
- * - * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission - * @param annotationType 注解类 - * @param 注解类型 - * @return 合成注解 - * @see SynthesizedAggregateAnnotation - */ - public static List getAllSynthesizedAnnotations(AnnotatedElement annotatedEle, Class 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()}顺序排序的注解对象集合 * + *

比如:
+ * 若{@code annotationType}为 A,且A存在元注解B,B又存在元注解C和D,则有: + *

+	 *                              |-> C.class [@a, @b]
+	 *     A.class -> B.class [@a] -|
+	 *                              |-> D.class [@a, @c]
+	 * 
+ * 扫描A,则该方法最终将返回 {@code [@a, @a, @b, @a, @c]} + * * @param annotationType 注解类 * @return 注解对象集合 * @see MetaAnnotationScanner @@ -432,6 +348,16 @@ public class AnnotationUtil { * * 注解根据其声明类/接口被扫描的顺序排序,若注解都在同一个{@link Class}中被声明,则还会遵循{@link Class#getAnnotations()}的顺序。 * + *

比如:
+ * 若{@code targetClass}为{@code A.class},且{@code A.class}存在父类{@code B.class}、父接口{@code C.class}, + * 三个类的注解声明情况如下: + *

+	 *                   |-> B.class [@a, @b]
+	 *     A.class [@a] -|
+	 *                   |-> C.class [@a, @c]
+	 * 
+ * 则该方法最终将返回 {@code [@a, @a, @b, @a, @c]} + * * @param targetClass 类 * @return 注解对象集合 * @see TypeAnnotationScanner @@ -452,6 +378,14 @@ public class AnnotationUtil { * * 方法上的注解根据方法的声明类/接口被扫描的顺序排序,若注解都在同一个类的同一个方法中被声明,则还会遵循{@link Method#getAnnotations()}的顺序。 * + *

比如:
+ * 若方法X声明于{@code A.class},且重载/重写自父类{@code B.class},并且父类中的方法X由重写至其实现的接口{@code C.class}, + * 三个类的注解声明情况如下: + *

+	 *     A#X()[@a] -> B#X()[@b] -> C#X()[@c]
+	 * 
+ * 则该方法最终将返回 {@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 注解类型 + * @return 别名支持后的注解 + * @since 5.7.23 + */ + public static T getAnnotationAlias(AnnotatedElement annotationEle, Class annotationType) { + final T annotation = getAnnotation(annotationEle, annotationType); + return aggregatingFromAnnotation(annotation).synthesize(annotationType); + } + + /** + * 将指定注解实例与其元注解转为合成注解 + * + * @param annotationType 注解类 + * @param annotations 注解对象 + * @param 注解类型 + * @return 合成注解 + * @see SynthesizedAggregateAnnotation + */ + public static T getSynthesizedAnnotation(Class annotationType, Annotation... annotations) { + // TODO 缓存合成注解信息,避免重复解析 + return Opt.ofNullable(annotations) + .filter(ArrayUtil::isNotEmpty) + .map(AnnotationUtil::aggregatingFromAnnotationWithMeta) + .map(a -> a.synthesize(annotationType)) + .get(); + } + + /** + *

获取元素上距离指定元素最接近的合成注解 + *

    + *
  • 若元素是类,则递归解析全部父类和全部父接口上的注解;
  • + *
  • 若元素是方法、属性或注解,则只解析其直接声明的注解;
  • + *
+ * + *

注解合成规则如下: + * 若{@code AnnotatedEle}按顺序从上到下声明了A,B,C三个注解,且三注解存在元注解如下: + *

+	 *    A -> MA1 -> MA2
+	 *    B -> MB1 -> MB2
+	 *    C -> MC1
+	 * 
+ * 此时入参{@code annotationType}类型为{@code MB1},则最终将优先返回基于根注解B合成的合成注解 + * + * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationType 注解类 + * @param 注解类型 + * @return 合成注解 + * @see SynthesizedAggregateAnnotation + */ + public static T getSynthesizedAnnotation(AnnotatedElement annotatedEle, Class 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); + } + + /** + * 获取元素上所有指定注解 + *
    + *
  • 若元素是类,则递归解析全部父类和全部父接口上的注解;
  • + *
  • 若元素是方法、属性或注解,则只解析其直接声明的注解;
  • + *
+ * + *

注解合成规则如下: + * 若{@code AnnotatedEle}按顺序从上到下声明了A,B,C三个注解,且三注解存在元注解如下: + *

+	 *    A -> M1 -> M2
+	 *    B -> M3 -> M1
+	 *    C -> M2
+	 * 
+ * 此时入参{@code annotationType}类型为{@code M1},则最终将返回基于根注解A与根注解B合成的合成注解。 + * + * @param annotatedEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationType 注解类 + * @param 注解类型 + * @return 合成注解 + * @see SynthesizedAggregateAnnotation + */ + public static List getAllSynthesizedAnnotations(AnnotatedElement annotatedEle, Class 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()); + } + /** * 方法是否为注解属性方法。
* 方法无参数,且有返回值的方法认为是注解属性的方法。 @@ -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); - } - } diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java b/hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java index 63ad83080..303424995 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/GenericSynthesizedAnnotation.java @@ -19,7 +19,7 @@ import java.util.stream.Stream; * @param 注解类型 * @author huangchengxing */ -public class GenericSynthesizedAnnotation implements Annotation, SynthesizedAnnotation { +public class GenericSynthesizedAnnotation implements SynthesizedAnnotation { private final R root; private final T annotation;