diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java
index 62c81f338..34ee2974b 100644
--- a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotatedElementUtil.java
@@ -103,8 +103,8 @@ import java.util.stream.Stream;
* 该属性类型为注解数组,且数组中注解被{@link java.lang.annotation.Repeatable}注解,
* 则认为被包括的注解为可重复注解;
* eg:
- * A上存在注解X,该注解是一个容器注解,内部可重复注解Y,
- * 包含解析后,得到注解X与它包含的可重复注解Y;
+ * A上存在注解X,该注解是一个容器注解,内部包含可重复注解Y,
+ * 解析X后,得到注解X与它包含的可重复注解Y;
*
*
缓存 + *
为了避免注解以及{@link AnnotatedElement}层级结构解析过程中的大量反射调用,
+ * 工具类为{@link AnnotatedElement}及其元注解信息进行了缓存。 若一个注解是可重复注解的容器注解,则尝试通过其属性获得获得包含的注解对象。
* 若包含的注解对象也是可重复注解的容器注解,则继续解析直到获得所有非容器注解为止。
+ * 缓存功能默认基于{@link WeakConcurrentMap}实现,会在gc时自动回收部分缓存数据。
+ * 但是若有必要,也可以调用{@link #clearCaches()}方法主动清空缓存。
+ *
* @author huangchengxing
* @see ResolvedAnnotationMapping
* @see GenericAnnotationMapping
@@ -650,7 +656,7 @@ public class AnnotatedElementUtil {
* @param element {@link AnnotatedElement}
* @return {@link MetaAnnotatedElement}实例
*/
- private static MetaAnnotatedElement
+ *
+ *
+ * @see AnnotationUtil#clearCaches()
+ * @see RepeatableAnnotationCollector#clearSingletonCaches()
+ */
+ public static void clearCaches() {
+ ELEMENT_CACHE.clear();
+ RESOLVED_ELEMENT_CACHE.clear();
+ REPEATABLE_ELEMENT_CACHE.clear();
+ RESOLVED_REPEATABLE_ELEMENT_CACHE.clear();
+ RepeatableAnnotationCollector.clearSingletonCaches();
+ AnnotationUtil.clearCaches();
+ }
+
/**
* 由一组注解聚合来的{@link AnnotatedElement}
*/
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 b5dd123c5..6691928d6 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
@@ -354,4 +354,11 @@ public class AnnotationUtil {
&& !attribute.isSynthetic();
}
+ /**
+ * 清空相关缓存
+ */
+ public static void clearCaches() {
+ DECLARED_ANNOTATIONS_CACHE.clear();
+ }
+
}
diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/RepeatableAnnotationCollector.java b/hutool-core/src/main/java/cn/hutool/core/annotation/RepeatableAnnotationCollector.java
index 1daae6cdb..cf6fe2bed 100644
--- a/hutool-core/src/main/java/cn/hutool/core/annotation/RepeatableAnnotationCollector.java
+++ b/hutool-core/src/main/java/cn/hutool/core/annotation/RepeatableAnnotationCollector.java
@@ -86,6 +86,14 @@ public interface RepeatableAnnotationCollector {
return Full.INSTANCE;
}
+ /**
+ * 清空单例缓存
+ */
+ static void clearSingletonCaches() {
+ Standard.INSTANCE.repeatableMethodCache.clear();
+ Full.INSTANCE.repeatableMethodCache.clear();
+ }
+
/**
*
diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotatedElementUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotatedElementUtilTest.java
index 5585b657e..7445efde8 100644
--- a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotatedElementUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotatedElementUtilTest.java
@@ -37,6 +37,31 @@ public class AnnotatedElementUtilTest {
ANNOTATION6, ANNOTATION5 // Interface.class's annotations
};
+ @Test
+ public void testClearCaches() {
+ AnnotatedElement type = Foo.class;
+
+ AnnotatedElement element = AnnotatedElementUtil.getResolvedMetaElementCache(type);
+ Assert.assertSame(element, AnnotatedElementUtil.getResolvedMetaElementCache(type));
+ AnnotatedElementUtil.clearCaches();
+ Assert.assertNotSame(element, AnnotatedElementUtil.getResolvedMetaElementCache(type));
+
+ element = AnnotatedElementUtil.getMetaElementCache(type);
+ Assert.assertSame(element, AnnotatedElementUtil.getMetaElementCache(type));
+ AnnotatedElementUtil.clearCaches();
+ Assert.assertNotSame(element, AnnotatedElementUtil.getMetaElementCache(type));
+
+ element = AnnotatedElementUtil.getResolvedRepeatableMetaElementCache(type);
+ Assert.assertSame(element, AnnotatedElementUtil.getResolvedRepeatableMetaElementCache(type));
+ AnnotatedElementUtil.clearCaches();
+ Assert.assertNotSame(element, AnnotatedElementUtil.getResolvedRepeatableMetaElementCache(type));
+
+ element = AnnotatedElementUtil.getRepeatableMetaElementCache(type);
+ Assert.assertSame(element, AnnotatedElementUtil.getRepeatableMetaElementCache(type));
+ AnnotatedElementUtil.clearCaches();
+ Assert.assertNotSame(element, AnnotatedElementUtil.getRepeatableMetaElementCache(type));
+ }
+
@Test
public void testIsAnnotated() {
Assert.assertTrue(AnnotatedElementUtil.isAnnotated(Foo.class, Annotation1.class));
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 a1f1eb380..6053d8851 100755
--- a/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AnnotationUtilTest.java
@@ -19,6 +19,9 @@ public class AnnotationUtilTest {
Annotation[] annotations = AnnotationUtil.getDeclaredAnnotations(ClassForTest.class);
Assert.assertArrayEquals(annotations, ClassForTest.class.getDeclaredAnnotations());
Assert.assertSame(annotations, AnnotationUtil.getDeclaredAnnotations(ClassForTest.class));
+
+ AnnotationUtil.clearCaches();
+ Assert.assertNotSame(annotations, AnnotationUtil.getDeclaredAnnotations(ClassForTest.class));
}
@Test