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 be44f080a..c84de0073 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationUtil.java @@ -4,18 +4,14 @@ import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ReflectUtil; -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.annotation.*; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; /** * 注解工具类
@@ -50,6 +46,47 @@ public class AnnotationUtil { return (null == annotationEle) ? null : (isToCombination ? toCombination(annotationEle) : annotationEle).getAnnotations(); } + /** + * 获取可重复的注解列表 + * 用于带有同一个注解的多个组合注解 + * + * @param annotationEle {@link AnnotatedElement},可以是Class、Method、Field、Constructor、ReflectPermission + * @param annotationType 注解类型 + * @return 注解列表 + * @param 注解值类型 + */ + public static Set getRepeatedAnnotations(AnnotatedElement annotationEle, Class annotationType) { + if (!Annotation.class.isAssignableFrom(annotationType)){ + return null; + } + Set annotationList = new HashSet<>(); + recursion(annotationList, annotationEle.getAnnotations(), annotationType); + return annotationList; + } + + /** + * 递归获取注解列表 + * + * @param list 注解结果集 + * @param annotations 注解参数集 + * @param annotationType 注解类型 + * @param 注解值类型 + */ + private static void recursion(Set list, Annotation[] annotations, Class annotationType) { + for (Annotation annotation : annotations) { + Class clazz = annotation.getClass(); + if (annotationType.isAssignableFrom(clazz)) { + list.add((T) annotation); + } else if (!Retention.class.isAssignableFrom(clazz) + && !Target.class.isAssignableFrom(clazz) + && !Documented.class.isAssignableFrom(clazz) + && !Repeatable.class.isAssignableFrom(clazz) + && !Inherited.class.isAssignableFrom(clazz)) { + recursion(list, annotation.annotationType().getAnnotations(), annotationType); + } + } + } + /** * 获取指定注解 * diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java index 3340dcf37..c3077a626 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java @@ -3,7 +3,14 @@ package cn.hutool.core.annotation; import org.junit.Assert; import org.junit.Test; +import java.util.Set; + public class AnnotationUtilTest { + @Test + public void getRepeatAnnotationValueTest(){ + Set annotations = AnnotationUtil.getRepeatedAnnotations(ClassWithAnnotation.class, AnnotationForTest.class); + Assert.assertTrue(annotations != null && annotations.size() == 2); + } @Test public void getAnnotationValueTest() { @@ -23,6 +30,7 @@ public class AnnotationUtilTest { } @AnnotationForTest("测试") + @RepeatAnnotationForTest static class ClassWithAnnotation{ public void test(){ diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/RepeatAnnotationForTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/RepeatAnnotationForTest.java new file mode 100644 index 000000000..cc71c68da --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/RepeatAnnotationForTest.java @@ -0,0 +1,16 @@ +package cn.hutool.core.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author hongda.li 2022-04-26 17:09 + */ +@AnnotationForTest("repeat-annotation") +@Retention(RetentionPolicy.RUNTIME) +// Target注解决定MyAnnotation注解可以加在哪些成分上,如加在类身上,或者属性身上,或者方法身上等成分 +@Target({ ElementType.METHOD, ElementType.TYPE }) +public @interface RepeatAnnotationForTest { +}