From 931965301b28f19ece802c45a178e3bf772c796e Mon Sep 17 00:00:00 2001 From: huangchengxing <841396397@qq.com> Date: Sat, 16 Jul 2022 13:18:55 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E5=8F=96=E6=B3=A8=E8=A7=A3=E5=90=88?= =?UTF-8?q?=E6=88=90=E7=9B=B8=E5=85=B3=E9=80=BB=E8=BE=91=E8=87=B3=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3=E5=90=88=E6=88=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractAnnotationSynthesizer.java | 148 +++++++++++++++++ .../AbstractLinkAnnotationPostProcessor.java | 20 +-- .../AbstractSynthesizedAnnotation.java | 15 +- .../AliasAnnotationPostProcessor.java | 2 +- .../AliasLinkAnnotationPostProcessor.java | 18 +- .../annotation/AnnotationSynthesizer.java | 77 +++++++++ .../MirrorLinkAnnotationPostProcessor.java | 12 +- .../SynthesizedAggregateAnnotation.java | 45 +---- .../annotation/SynthesizedAnnotation.java | 9 +- .../SynthesizedAnnotationPostProcessor.java | 4 +- .../SynthesizedMetaAggregateAnnotation.java | 156 +++++------------- .../annotation/SyntheticAnnotationProxy.java | 25 +-- .../AliasAnnotationPostProcessorTest.java | 14 +- .../AliasLinkAnnotationPostProcessorTest.java | 14 +- ...sizedAnnotationAttributeProcessorTest.java | 5 - ...MirrorLinkAnnotationPostProcessorTest.java | 14 +- .../SynthesizedAnnotationSelectorTest.java | 5 - .../SyntheticMetaAnnotationTest.java | 2 +- 18 files changed, 331 insertions(+), 254 deletions(-) create mode 100644 hutool-core/src/main/java/cn/hutool/core/annotation/AbstractAnnotationSynthesizer.java create mode 100644 hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationSynthesizer.java diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractAnnotationSynthesizer.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractAnnotationSynthesizer.java new file mode 100644 index 000000000..8f7ec7d76 --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractAnnotationSynthesizer.java @@ -0,0 +1,148 @@ +package cn.hutool.core.annotation; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.map.MapUtil; +import cn.hutool.core.util.ObjectUtil; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Comparator; +import java.util.Map; + +/** + * {@link AnnotationSynthesizer}的基本实现 + * + * @author huangchengxing + */ +public abstract class AbstractAnnotationSynthesizer implements AnnotationSynthesizer { + + /** + * 合成注解来源最初来源 + */ + protected final T source; + + /** + * 包含根注解以及其元注解在内的全部注解实例 + */ + protected final Map, SynthesizedAnnotation> synthesizedAnnotationMap; + + /** + * 合成注解选择器 + */ + protected final SynthesizedAnnotationSelector annotationSelector; + + /** + * 合成注解属性处理器 + */ + protected final Collection postProcessors; + + /** + * 基于指定根注解,为其层级结构中的全部注解构造一个合成注解 + * + * @param source 当前查找的注解对象 + * @param annotationSelector 合成注解选择器 + * @param annotationPostProcessors 注解后置处理器 + */ + protected AbstractAnnotationSynthesizer( + T source, SynthesizedAnnotationSelector annotationSelector, Collection annotationPostProcessors) { + Assert.notNull(source, "source must not null"); + Assert.notNull(annotationSelector, "annotationSelector must not null"); + Assert.notNull(annotationPostProcessors, "annotationPostProcessors must not null"); + + this.source = source; + this.annotationSelector = annotationSelector; + this.postProcessors = CollUtil.unmodifiable( + CollUtil.sort(annotationPostProcessors, Comparator.comparing(SynthesizedAnnotationPostProcessor::order)) + ); + this.synthesizedAnnotationMap = MapUtil.unmodifiable(loadAnnotations()); + annotationPostProcessors.forEach(processor -> + synthesizedAnnotationMap.values().forEach(synthesized -> processor.process(synthesized, this)) + ); + } + + /** + * 加载合成注解的必要属性 + * + * @return 合成注解 + */ + protected abstract Map, SynthesizedAnnotation> loadAnnotations(); + + /** + * 根据指定的注解类型和对应注解对象,合成最终所需的合成注解 + * + * @param annotationType 注解类型 + * @param annotation 合成注解对象 + * @param 注解类型 + * @return 最终所需的合成注解 + */ + protected abstract A synthesize(Class annotationType, SynthesizedAnnotation annotation); + + /** + * 获取合成注解来源最初来源 + * + * @return 合成注解来源最初来源 + */ + @Override + public T getSource() { + return source; + } + + /** + * 合成注解选择器 + * + * @return 注解选择器 + */ + @Override + public SynthesizedAnnotationSelector getAnnotationSelector() { + return annotationSelector; + } + + /** + * 获取合成注解后置处理器 + * + * @return 合成注解后置处理器 + */ + @Override + public Collection getAnnotationPostProcessors() { + return postProcessors; + } + + /** + * 获取已合成的注解 + * + * @param annotationType 注解类型 + * @return 已合成的注解 + */ + @Override + public SynthesizedAnnotation getSynthesizedAnnotation(Class annotationType) { + return synthesizedAnnotationMap.get(annotationType); + } + + /** + * 获取全部的合成注解 + * + * @return 合成注解 + */ + @Override + public Map, SynthesizedAnnotation> getAllSynthesizedAnnotation() { + return synthesizedAnnotationMap; + } + + /** + * 获取合成注解 + * + * @param annotationType 注解类型 + * @param 注解类型 + * @return 类型 + */ + @Override + public A synthesize(Class annotationType) { + SynthesizedAnnotation synthesizedAnnotation = synthesizedAnnotationMap.get(annotationType); + if (ObjectUtil.isNull(synthesizedAnnotation)) { + return null; + } + return synthesize(annotationType, synthesizedAnnotation); + } + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractLinkAnnotationPostProcessor.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractLinkAnnotationPostProcessor.java index d510176ad..578bb6fde 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractLinkAnnotationPostProcessor.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractLinkAnnotationPostProcessor.java @@ -26,10 +26,10 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized * {@link #processLinkedAttribute}处理。 * * @param synthesizedAnnotation 合成的注解 - * @param aggregator 合成注解聚合器 + * @param synthesizer 合成注解聚合器 */ @Override - public void process(SynthesizedAnnotation synthesizedAnnotation, SynthesizedAggregateAnnotation aggregator) { + public void process(SynthesizedAnnotation synthesizedAnnotation, AnnotationSynthesizer synthesizer) { final Map attributeMap = new HashMap<>(synthesizedAnnotation.getAttributes()); attributeMap.forEach((originalAttributeName, originalAttribute) -> { // 获取注解 @@ -38,14 +38,14 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized return; } // 获取注解属性 - final SynthesizedAnnotation linkedAnnotation = getLinkedAnnotation(link, aggregator, synthesizedAnnotation.annotationType()); + final SynthesizedAnnotation linkedAnnotation = getLinkedAnnotation(link, synthesizer, synthesizedAnnotation.annotationType()); if (ObjectUtil.isNull(linkedAnnotation)) { return; } final AnnotationAttribute linkedAttribute = linkedAnnotation.getAttributes().get(link.attribute()); // 处理 processLinkedAttribute( - aggregator, link, + synthesizer, link, synthesizedAnnotation, synthesizedAnnotation.getAttributes().get(originalAttributeName), linkedAnnotation, linkedAttribute ); @@ -64,7 +64,7 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized /** * 对关联的合成注解对象及其关联属性的处理 * - * @param aggregator 合成注解聚合器 + * @param synthesizer 注解合成器 * @param annotation {@code originalAttribute}上的{@link Link}注解对象 * @param originalAnnotation 当前正在处理的{@link SynthesizedAnnotation}对象 * @param originalAttribute {@code originalAnnotation}上的待处理的属性 @@ -72,7 +72,7 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized * @param linkedAttribute {@link Link}指向的{@code originalAnnotation}中的关联属性,该参数可能为空 */ protected abstract void processLinkedAttribute( - SynthesizedAggregateAnnotation aggregator, Link annotation, + AnnotationSynthesizer synthesizer, Link annotation, SynthesizedAnnotation originalAnnotation, AnnotationAttribute originalAttribute, SynthesizedAnnotation linkedAnnotation, AnnotationAttribute linkedAttribute ); @@ -96,13 +96,13 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized /** * 从合成注解中获取{@link Link#type()}指定的注解对象 * - * @param annotation {@link Link}注解 - * @param synthesizedAnnotationAggregator 合成注解 + * @param annotation {@link Link}注解 + * @param synthesizer 注解合成器 */ protected SynthesizedAnnotation getLinkedAnnotation( - Link annotation, SynthesizedAggregateAnnotation synthesizedAnnotationAggregator, Class defaultType) { + Link annotation, AnnotationSynthesizer synthesizer, Class defaultType) { final Class targetAnnotationType = getLinkedAnnotationType(annotation, defaultType); - return synthesizedAnnotationAggregator.getSynthesizedAnnotation(targetAnnotationType); + return synthesizer.getSynthesizedAnnotation(targetAnnotationType); } /** diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractSynthesizedAnnotation.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractSynthesizedAnnotation.java index c8b906cc5..a8a19c4cc 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractSynthesizedAnnotation.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AbstractSynthesizedAnnotation.java @@ -20,7 +20,6 @@ import java.util.stream.Stream; */ public abstract class AbstractSynthesizedAnnotation implements Annotation, SynthesizedAnnotation { - private final SynthesizedAggregateAnnotation owner; private final R root; private final Annotation annotation; private final Map attributeMethodCaches; @@ -30,15 +29,13 @@ public abstract class AbstractSynthesizedAnnotation implements Annotation, Sy /** * 创建一个合成注解 * - * @param owner 合成注解所属的合成注解聚合器 * @param root 根对象 * @param annotation 被合成的注解对象 * @param verticalDistance 距离根对象的水平距离 * @param horizontalDistance 距离根对象的垂直距离 */ protected AbstractSynthesizedAnnotation( - SynthesizedAggregateAnnotation owner, R root, Annotation annotation, int verticalDistance, int horizontalDistance) { - this.owner = owner; + R root, Annotation annotation, int verticalDistance, int horizontalDistance) { this.root = root; this.annotation = annotation; this.verticalDistance = verticalDistance; @@ -130,16 +127,6 @@ public abstract class AbstractSynthesizedAnnotation implements Annotation, Sy .get(); } - /** - * 获取所属的合成注解集合器 - * - * @return 合成注解 - */ - @Override - public SynthesizedAggregateAnnotation getOwner() { - return owner; - } - /** * 获取该合成注解对应的根节点 * diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AliasAnnotationPostProcessor.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AliasAnnotationPostProcessor.java index fe8aa890d..ac5481a27 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AliasAnnotationPostProcessor.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AliasAnnotationPostProcessor.java @@ -27,7 +27,7 @@ public class AliasAnnotationPostProcessor implements SynthesizedAnnotationPostPr } @Override - public void process(SynthesizedAnnotation synthesizedAnnotation, SynthesizedAggregateAnnotation aggregator) { + public void process(SynthesizedAnnotation synthesizedAnnotation, AnnotationSynthesizer synthesizer) { final Map attributeMap = synthesizedAnnotation.getAttributes(); // 记录别名与属性的关系 diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessor.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessor.java index d5fe28f18..0cf5b2255 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessor.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessor.java @@ -43,7 +43,7 @@ public class AliasLinkAnnotationPostProcessor extends AbstractLinkAnnotationPost * 将目标注解属性包装为{@link AliasedAnnotationAttribute}或{@link ForceAliasedAnnotationAttribute}, * 然后用包装后注解属性在对应的合成注解中替换原始的目标注解属性 * - * @param aggregator 合成注解聚合器 + * @param synthesizer 注解合成器 * @param annotation {@code originalAttribute}上的{@link Link}注解对象 * @param originalAnnotation 当前正在处理的{@link SynthesizedAnnotation}对象 * @param originalAttribute {@code originalAnnotation}上的待处理的属性 @@ -52,34 +52,34 @@ public class AliasLinkAnnotationPostProcessor extends AbstractLinkAnnotationPost */ @Override protected void processLinkedAttribute( - SynthesizedAggregateAnnotation aggregator, Link annotation, + AnnotationSynthesizer synthesizer, Link annotation, SynthesizedAnnotation originalAnnotation, AnnotationAttribute originalAttribute, SynthesizedAnnotation linkedAnnotation, AnnotationAttribute linkedAttribute) { // 校验别名关系 checkAliasRelation(annotation, originalAttribute, linkedAttribute); // 处理aliasFor类型的关系 if (RelationType.ALIAS_FOR.equals(annotation.type())) { - wrappingLinkedAttribute(aggregator, originalAttribute, linkedAttribute, AliasedAnnotationAttribute::new); + wrappingLinkedAttribute(synthesizer, originalAttribute, linkedAttribute, AliasedAnnotationAttribute::new); return; } // 处理forceAliasFor类型的关系 - wrappingLinkedAttribute(aggregator, originalAttribute, linkedAttribute, ForceAliasedAnnotationAttribute::new); + wrappingLinkedAttribute(synthesizer, originalAttribute, linkedAttribute, ForceAliasedAnnotationAttribute::new); } /** * 对指定注解属性进行包装,若该属性已被包装过,则递归以其为根节点的树结构,对树上全部的叶子节点进行包装 */ private void wrappingLinkedAttribute( - SynthesizedAggregateAnnotation synthesizedAnnotationAggregator, AnnotationAttribute originalAttribute, AnnotationAttribute aliasAttribute, BinaryOperator wrapping) { + AnnotationSynthesizer synthesizer, AnnotationAttribute originalAttribute, AnnotationAttribute aliasAttribute, BinaryOperator wrapping) { // 不是包装属性 if (!aliasAttribute.isWrapped()) { - processAttribute(synthesizedAnnotationAggregator, originalAttribute, aliasAttribute, wrapping); + processAttribute(synthesizer, originalAttribute, aliasAttribute, wrapping); return; } // 是包装属性 final AbstractWrappedAnnotationAttribute wrapper = (AbstractWrappedAnnotationAttribute)aliasAttribute; wrapper.getAllLinkedNonWrappedAttributes().forEach( - t -> processAttribute(synthesizedAnnotationAggregator, originalAttribute, t, wrapping) + t -> processAttribute(synthesizer, originalAttribute, t, wrapping) ); } @@ -87,10 +87,10 @@ public class AliasLinkAnnotationPostProcessor extends AbstractLinkAnnotationPost * 获取指定注解属性,然后将其再进行一层包装 */ private void processAttribute( - SynthesizedAggregateAnnotation synthesizedAnnotationAggregator, AnnotationAttribute originalAttribute, + AnnotationSynthesizer synthesizer, AnnotationAttribute originalAttribute, AnnotationAttribute target, BinaryOperator wrapping) { Opt.ofNullable(target.getAnnotationType()) - .map(synthesizedAnnotationAggregator::getSynthesizedAnnotation) + .map(synthesizer::getSynthesizedAnnotation) .ifPresent(t -> t.replaceAttribute(target.getAttributeName(), old -> wrapping.apply(old, originalAttribute))); } diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationSynthesizer.java b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationSynthesizer.java new file mode 100644 index 000000000..298a33dbc --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/AnnotationSynthesizer.java @@ -0,0 +1,77 @@ +package cn.hutool.core.annotation; + +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Map; + +/** + *

注解合成器,用于处理一组给定的与{@link #getSource()}具有直接或间接联系的注解对象, + * 并返回与原始注解对象具有不同属性的“合成”注解。 + * + *

合成注解一般被用于处理类层级结果中具有直接或间接关联的注解对象, + * 当实例被创建时,会获取到这些注解对象,并使用{@link SynthesizedAnnotationSelector}对类型相同的注解进行过滤, + * 并最终得到类型不重复的有效注解对象。这些有效注解将被包装为{@link SynthesizedAnnotation}, + * 然后最终用于“合成”一个{@link SynthesizedAggregateAnnotation}。
+ * {@link SynthesizedAnnotationSelector}是合成注解生命周期中的第一个钩子, + * 自定义选择器以拦截原始注解被扫描的过程。 + * + *

当合成注解完成对待合成注解的扫描,并完成了必要属性的加载后, + * 将会按顺序依次调用{@link SynthesizedAnnotationPostProcessor}, + * 注解后置处理器允许用于对完成注解的待合成注解进行二次调整, + * 该钩子一般用于根据{@link Link}注解对属性进行调整。
+ * {@link SynthesizedAnnotationPostProcessor}是合成注解生命周期中的第二个钩子, + * 自定义后置处理器以拦截原始在转为待合成注解后的初始化过程。 + * + *

使用{@link #synthesize(Class)}用于获取“合成”后的注解, + * 该注解对象的属性可能会与原始的对象属性不同。 + * + * @author huangchengxing + */ +public interface AnnotationSynthesizer { + + /** + * 获取合成注解来源最初来源 + * + * @return 合成注解来源最初来源 + */ + Object getSource(); + + /** + * 合成注解选择器 + * + * @return 注解选择器 + */ + SynthesizedAnnotationSelector getAnnotationSelector(); + + /** + * 获取合成注解后置处理器 + * + * @return 合成注解后置处理器 + */ + Collection getAnnotationPostProcessors(); + + /** + * 获取已合成的注解 + * + * @param annotationType 注解类型 + * @return 已合成的注解 + */ + SynthesizedAnnotation getSynthesizedAnnotation(Class annotationType); + + /** + * 获取全部的合成注解 + * + * @return 合成注解 + */ + Map, SynthesizedAnnotation> getAllSynthesizedAnnotation(); + + /** + * 获取合成注解 + * + * @param annotationType 注解类型 + * @param 注解类型 + * @return 类型 + */ + T synthesize(Class annotationType); + +} diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java b/hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java index f523473e8..1fc0a203b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessor.java @@ -1,8 +1,8 @@ package cn.hutool.core.annotation; import cn.hutool.core.lang.Assert; +import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ObjectUtil; -import cn.hutool.core.util.StrUtil; /** *

用于处理注解对象中带有{@link Link}注解,且{@link Link#type()}为{@link RelationType#MIRROR_FOR}的属性。
@@ -36,7 +36,7 @@ public class MirrorLinkAnnotationPostProcessor extends AbstractLinkAnnotationPos * 将存在镜像关系的合成注解属性分别包装为{@link MirroredAnnotationAttribute}对象, * 并使用包装后{@link MirroredAnnotationAttribute}替换在它们对应合成注解实例中的{@link AnnotationAttribute} * - * @param aggregator 合成注解聚合器 + * @param synthesizer 注解合成器 * @param annotation {@code originalAttribute}上的{@link Link}注解对象 * @param originalAnnotation 当前正在处理的{@link SynthesizedAnnotation}对象 * @param originalAttribute {@code originalAnnotation}上的待处理的属性 @@ -45,7 +45,7 @@ public class MirrorLinkAnnotationPostProcessor extends AbstractLinkAnnotationPos */ @Override protected void processLinkedAttribute( - SynthesizedAggregateAnnotation aggregator, Link annotation, + AnnotationSynthesizer synthesizer, Link annotation, SynthesizedAnnotation originalAnnotation, AnnotationAttribute originalAttribute, SynthesizedAnnotation linkedAnnotation, AnnotationAttribute linkedAttribute) { @@ -86,21 +86,21 @@ public class MirrorLinkAnnotationPostProcessor extends AbstractLinkAnnotationPos String errorMsg; // 原始字段已经跟其他字段形成镜像 if (originalAttributeMirrored && !mirrorAttributeMirrored) { - errorMsg = StrUtil.format( + errorMsg = CharSequenceUtil.format( "attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}]", original.getAttribute(), mirror.getAttribute(), ((MirroredAnnotationAttribute)original).getLinked() ); } // 镜像字段已经跟其他字段形成镜像 else if (!originalAttributeMirrored && mirrorAttributeMirrored) { - errorMsg = StrUtil.format( + errorMsg = CharSequenceUtil.format( "attribute [{}] cannot mirror for [{}], because it's already mirrored for [{}]", mirror.getAttribute(), original.getAttribute(), ((MirroredAnnotationAttribute)mirror).getLinked() ); } // 两者都形成了镜像,但是都未指向对方,理论上不会存在该情况 else { - errorMsg = StrUtil.format( + errorMsg = CharSequenceUtil.format( "attribute [{}] cannot mirror for [{}], because [{}] already mirrored for [{}] and [{}] already mirrored for [{}]", mirror.getAttribute(), original.getAttribute(), mirror.getAttribute(), ((MirroredAnnotationAttribute)mirror).getLinked(), diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java index b2d047bb6..50ffadf7b 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAggregateAnnotation.java @@ -1,10 +1,10 @@ package cn.hutool.core.annotation; import java.lang.annotation.Annotation; -import java.util.Collection; /** - * 表示基于特定规则聚合,将一组注解聚合而来的注解对象 + *

表示基于特定规则聚合,将一组注解聚合而来的注解对象, + * 该注解对象允许根据一定规则“合成”一些跟原始注解属性不一样合成注解。 * *

合成注解一般被用于处理类层级结果中具有直接或间接关联的注解对象, * 当实例被创建时,会获取到这些注解对象,并使用{@link SynthesizedAnnotationSelector}对类型相同的注解进行过滤, @@ -28,13 +28,14 @@ import java.util.Collection; * 自定义属性处理器以拦截合成注解的取值过程。 * * @author huangchengxing + * @see AnnotationSynthesizer * @see SynthesizedAnnotation * @see SynthesizedAnnotationSelector * @see SynthesizedAnnotationAttributeProcessor * @see SynthesizedAnnotationPostProcessor * @see SynthesizedMetaAggregateAnnotation */ -public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnnotation, Hierarchical { +public interface SynthesizedAggregateAnnotation extends AggregateAnnotation, Hierarchical, AnnotationSynthesizer { // ================== hierarchical ================== @@ -71,13 +72,6 @@ public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnn */ T getAnnotation(Class annotationType); - /** - * 获取合成注解选择器 - * - * @return 合成注解选择器 - */ - SynthesizedAnnotationSelector getAnnotationSelector(); - /** * 获取合成注解属性处理器 * @@ -85,28 +79,6 @@ public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnn */ SynthesizedAnnotationAttributeProcessor getAnnotationAttributeProcessor(); - /** - * 获取合成注解属性后置处理器 - * - * @return 合成注解属性后置处理器 - */ - Collection getAnnotationAttributePostProcessors(); - - /** - * 获取已合成的注解 - * - * @param annotationType 注解类型 - * @return 已合成的注解 - */ - SynthesizedAnnotation getSynthesizedAnnotation(Class annotationType); - - /** - * 获取全部的合成注解 - * - * @return 合成注解 - */ - Collection getAllSynthesizedAnnotation(); - /** * 获取当前的注解类型 * @@ -126,15 +98,6 @@ public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnn */ Object getAttribute(String attributeName, Class attributeType); - /** - * 获取合成注解 - * - * @param annotationType 注解类型 - * @param 注解类型 - * @return 类型 - */ - T synthesize(Class annotationType); - /** * 基于指定根注解,构建包括其元注解在内的合成注解 * diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java index b65370ba2..b97bfbb7e 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotation.java @@ -8,7 +8,7 @@ import java.util.function.UnaryOperator; /** *

用于在{@link SynthesizedAggregateAnnotation}中表示一个处于合成状态的注解对象。
- * 当对多个合成注解排序时,默认使用{@link #DEFAULT_CHILD_PRIORITY_COMPARATOR}进行排序, + * 当对多个合成注解排序时,默认使用{@link #DEFAULT_HIERARCHICAL_COMPARATOR}进行排序, * 从保证合成注解按{@link #getVerticalDistance()}与{@link #getHorizontalDistance()}的返回值保持有序, * 从而使得距离根元素更接近的注解对象在被处理是具有更高的优先级。 * @@ -17,13 +17,6 @@ import java.util.function.UnaryOperator; */ public interface SynthesizedAnnotation extends Annotation, Hierarchical { - /** - * 获取所属的合成注解聚合器 - * - * @return 合成注解 - */ - SynthesizedAggregateAnnotation getOwner(); - /** * 获取被合成的注解对象 * diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java index cedff1f4d..91e701be8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/SynthesizedAnnotationPostProcessor.java @@ -64,8 +64,8 @@ public interface SynthesizedAnnotationPostProcessor extends Comparable implements SynthesizedAggregateAnnotation { /** * 根对象 @@ -67,26 +65,11 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA */ private final int horizontalDistance; - /** - * 包含根注解以及其元注解在内的全部注解实例 - */ - private final Map, SynthesizedAnnotation> metaAnnotationMap; - - /** - * 合成注解选择器 - */ - private final SynthesizedAnnotationSelector annotationSelector; - /** * 合成注解属性处理器 */ private final SynthesizedAnnotationAttributeProcessor attributeProcessor; - /** - * 合成注解属性处理器 - */ - private final List postProcessors; - /** * 基于指定根注解,为其层级结构中的全部注解构造一个合成注解。 * 当层级结构中出现了相同的注解对象时,将优先选择以距离根注解最近,且优先被扫描的注解对象, @@ -118,7 +101,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA Annotation annotation, SynthesizedAnnotationSelector annotationSelector, SynthesizedAnnotationAttributeProcessor attributeProcessor, - Collection annotationPostProcessors) { + Collection annotationPostProcessors) { this( null, 0, 0, annotation, annotationSelector, attributeProcessor, annotationPostProcessors @@ -131,40 +114,24 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA * @param root 根对象 * @param verticalDistance 距离根对象的水平距离 * @param horizontalDistance 距离根对象的垂直距离 - * @param annotation 当前查找的注解对象 + * @param source 当前查找的注解对象 * @param annotationSelector 合成注解选择器 * @param attributeProcessor 注解属性处理器 * @param annotationPostProcessors 注解后置处理器 */ SynthesizedMetaAggregateAnnotation( Object root, int verticalDistance, int horizontalDistance, - Annotation annotation, + Annotation source, SynthesizedAnnotationSelector annotationSelector, SynthesizedAnnotationAttributeProcessor attributeProcessor, - Collection annotationPostProcessors) { - Assert.notNull(annotation, "annotation must not null"); - Assert.notNull(annotationSelector, "annotationSelector must not null"); + Collection annotationPostProcessors) { + super(source, annotationSelector, annotationPostProcessors); Assert.notNull(attributeProcessor, "attributeProcessor must not null"); - Assert.notNull(annotationPostProcessors, "attributePostProcessors must not null"); - // 初始化坐标 this.root = ObjectUtil.defaultIfNull(root, this); this.verticalDistance = verticalDistance; this.horizontalDistance = horizontalDistance; - - // 初始化属性 - this.source = annotation; - this.annotationSelector = annotationSelector; this.attributeProcessor = attributeProcessor; - this.postProcessors = new ArrayList<>(annotationPostProcessors); - this.postProcessors.sort(Comparator.comparing(SynthesizedAnnotationPostProcessor::order)); - this.metaAnnotationMap = new LinkedHashMap<>(); - - // 初始化元注解信息,并进行后置处理 - loadMetaAnnotations(); - annotationPostProcessors.forEach(processor -> - metaAnnotationMap.values().forEach(synthesized -> processor.process(synthesized, this)) - ); } /** @@ -198,22 +165,26 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA } /** - * 获取根注解 - * - * @return 根注解 - */ - public Annotation getSource() { - return source; - } - - /** - * 获取合成注解选择器 - * - * @return 合成注解选择器 + * 按广度优先扫描{@link #source}上的元注解 */ @Override - public SynthesizedAnnotationSelector getAnnotationSelector() { - return this.annotationSelector; + protected Map, SynthesizedAnnotation> loadAnnotations() { + Assert.isFalse(SyntheticAnnotationProxy.isProxyAnnotation(source.getClass()), "source [{}] has been synthesized"); + Map, SynthesizedAnnotation> annotationMap = new LinkedHashMap<>(); + annotationMap.put(source.annotationType(), new MetaAnnotation(source, source, 0, 0)); + new MetaAnnotationScanner().scan( + (index, annotation) -> { + SynthesizedAnnotation oldAnnotation = annotationMap.get(annotation.annotationType()); + SynthesizedAnnotation newAnnotation = new MetaAnnotation(source, annotation, index, annotationMap.size()); + if (ObjectUtil.isNull(oldAnnotation)) { + annotationMap.put(annotation.annotationType(), newAnnotation); + } else { + annotationMap.put(annotation.annotationType(), annotationSelector.choose(oldAnnotation, newAnnotation)); + } + }, + source.annotationType(), null + ); + return annotationMap; } /** @@ -226,37 +197,6 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA return this.attributeProcessor; } - /** - * 获取合成注解属性后置处理器 - * - * @return 合成注解属性后置处理器 - */ - @Override - public Collection getAnnotationAttributePostProcessors() { - return this.postProcessors; - } - - /** - * 获取已合成的注解 - * - * @param annotationType 注解类型 - * @return 已合成的注解 - */ - @Override - public SynthesizedAnnotation getSynthesizedAnnotation(Class annotationType) { - return metaAnnotationMap.get(annotationType); - } - - /** - * 获取全部的已合成注解 - * - * @return 合成注解 - */ - @Override - public Collection getAllSynthesizedAnnotation() { - return metaAnnotationMap.values(); - } - /** * 根据指定的属性名与属性类型获取对应的属性值,若存在{@link Alias}则获取{@link Alias#value()}指定的别名属性的值 *

当不同层级的注解之间存在同名同类型属性时,将优先获取更接近根注解的属性 @@ -267,7 +207,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA */ @Override public Object getAttribute(String attributeName, Class attributeType) { - return attributeProcessor.getAttributeValue(attributeName, attributeType, metaAnnotationMap.values()); + return attributeProcessor.getAttributeValue(attributeName, attributeType, synthesizedAnnotationMap.values()); } /** @@ -280,7 +220,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA @Override public T getAnnotation(Class annotationType) { return Opt.ofNullable(annotationType) - .map(metaAnnotationMap::get) + .map(synthesizedAnnotationMap::get) .map(SynthesizedAnnotation::getAnnotation) .map(annotationType::cast) .orElse(null); @@ -294,7 +234,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA */ @Override public boolean isAnnotationPresent(Class annotationType) { - return metaAnnotationMap.containsKey(annotationType); + return synthesizedAnnotationMap.containsKey(annotationType); } /** @@ -304,7 +244,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA */ @Override public Annotation[] getAnnotations() { - return metaAnnotationMap.values().stream() + return synthesizedAnnotationMap.values().stream() .map(SynthesizedAnnotation::getAnnotation) .toArray(Annotation[]::new); } @@ -314,32 +254,11 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA * * @param annotationType 注解类型 * @return 合成注解对象 - * @see SyntheticAnnotationProxy#create(Class, SynthesizedAggregateAnnotation) + * @see SyntheticAnnotationProxy#create(Class, SynthesizedAggregateAnnotation, SynthesizedAnnotation) */ @Override - public T synthesize(Class annotationType) { - return SyntheticAnnotationProxy.create(annotationType, this); - } - - /** - * 广度优先遍历并缓存该根注解上的全部元注解 - */ - private void loadMetaAnnotations() { - Assert.isFalse(SyntheticAnnotationProxy.isProxyAnnotation(source.getClass()), "source [{}] has been synthesized"); - // 扫描元注解 - metaAnnotationMap.put(source.annotationType(), new MetaAnnotation(this, source, source, 0, 0)); - new MetaAnnotationScanner().scan( - (index, annotation) -> { - SynthesizedAnnotation oldAnnotation = metaAnnotationMap.get(annotation.annotationType()); - SynthesizedAnnotation newAnnotation = new MetaAnnotation(this, source, annotation, index, metaAnnotationMap.size()); - if (ObjectUtil.isNull(oldAnnotation)) { - metaAnnotationMap.put(annotation.annotationType(), newAnnotation); - } else { - metaAnnotationMap.put(annotation.annotationType(), annotationSelector.choose(oldAnnotation, newAnnotation)); - } - }, - source.annotationType(), null - ); + public T synthesize(Class annotationType, SynthesizedAnnotation annotation) { + return SyntheticAnnotationProxy.create(annotationType, this, annotation); } /** @@ -352,14 +271,13 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA /** * 创建一个合成注解 * - * @param owner 合成注解所属的合成注解聚合器 * @param root 根对象 * @param annotation 被合成的注解对象 * @param verticalDistance 距离根对象的水平距离 * @param horizontalDistance 距离根对象的垂直距离 */ - protected MetaAnnotation(SynthesizedAggregateAnnotation owner, Annotation root, Annotation annotation, int verticalDistance, int horizontalDistance) { - super(owner, root, annotation, verticalDistance, horizontalDistance); + protected MetaAnnotation(Annotation root, Annotation annotation, int verticalDistance, int horizontalDistance) { + super(root, annotation, verticalDistance, horizontalDistance); } } diff --git a/hutool-core/src/main/java/cn/hutool/core/annotation/SyntheticAnnotationProxy.java b/hutool-core/src/main/java/cn/hutool/core/annotation/SyntheticAnnotationProxy.java index f107c290e..e5ef1beb8 100644 --- a/hutool-core/src/main/java/cn/hutool/core/annotation/SyntheticAnnotationProxy.java +++ b/hutool-core/src/main/java/cn/hutool/core/annotation/SyntheticAnnotationProxy.java @@ -2,10 +2,10 @@ package cn.hutool.core.annotation; import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Opt; +import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.ClassUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; -import cn.hutool.core.util.StrUtil; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; @@ -25,11 +25,14 @@ import java.util.stream.Stream; */ class SyntheticAnnotationProxy implements InvocationHandler { + private final SynthesizedAggregateAnnotation aggregateAnnotation; private final SynthesizedAnnotation annotation; private final Map> methods; - SyntheticAnnotationProxy(SynthesizedAnnotation annotation) { + SyntheticAnnotationProxy(SynthesizedAggregateAnnotation aggregateAnnotation, SynthesizedAnnotation annotation) { + Assert.notNull(aggregateAnnotation, "aggregateAnnotation must not null"); Assert.notNull(annotation, "annotation must not null"); + this.aggregateAnnotation = aggregateAnnotation; this.annotation = annotation; this.methods = new HashMap<>(9); loadMethods(); @@ -43,17 +46,16 @@ class SyntheticAnnotationProxy implements InvocationHandler { * * * @param annotationType 注解类型 - * @param synthesizedAnnotationAggregator 合成注解 + * @param aggregateAnnotation 合成注解 * @return 代理注解 */ @SuppressWarnings("unchecked") static T create( - Class annotationType, SynthesizedAggregateAnnotation synthesizedAnnotationAggregator) { - final SynthesizedAnnotation annotation = synthesizedAnnotationAggregator.getSynthesizedAnnotation(annotationType); + Class annotationType, SynthesizedAggregateAnnotation aggregateAnnotation, SynthesizedAnnotation annotation) { if (ObjectUtil.isNull(annotation)) { return null; } - final SyntheticAnnotationProxy proxyHandler = new SyntheticAnnotationProxy(annotation); + final SyntheticAnnotationProxy proxyHandler = new SyntheticAnnotationProxy(aggregateAnnotation, annotation); if (ObjectUtil.isNull(annotation)) { return null; } @@ -91,7 +93,6 @@ class SyntheticAnnotationProxy implements InvocationHandler { throw new UnsupportedOperationException("proxied annotation can not reset attributes"); }); methods.put("getAttributeValue", (method, args) -> annotation.getAttributeValue((String)args[0])); - methods.put("getOwner", (method, args) -> annotation.getOwner()); methods.put("annotationType", (method, args) -> annotation.annotationType()); for (final Method declaredMethod : ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType())) { methods.put(declaredMethod.getName(), (method, args) -> proxyAttributeValue(method)); @@ -101,17 +102,17 @@ class SyntheticAnnotationProxy implements InvocationHandler { private String proxyToString() { final String attributes = Stream.of(ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType())) .filter(AnnotationUtil::isAttributeMethod) - .map(method -> StrUtil.format("{}={}", method.getName(), annotation.getOwner().getAttribute(method.getName(), method.getReturnType()))) + .map(method -> CharSequenceUtil.format("{}={}", method.getName(), aggregateAnnotation.getAttribute(method.getName(), method.getReturnType()))) .collect(Collectors.joining(", ")); - return StrUtil.format("@{}({})", annotation.annotationType().getName(), attributes); + return CharSequenceUtil.format("@{}({})", annotation.annotationType().getName(), attributes); } private int proxyHashCode() { - return Objects.hash(annotation.getOwner(), annotation); + return Objects.hash(aggregateAnnotation, annotation); } private Object proxyGetSynthesizedAnnotationAggregator() { - return annotation.getOwner(); + return aggregateAnnotation; } private Object proxyGetSynthesizedAnnotation() { @@ -119,7 +120,7 @@ class SyntheticAnnotationProxy implements InvocationHandler { } private Object proxyAttributeValue(Method attributeMethod) { - return annotation.getOwner().getAttribute(attributeMethod.getName(), attributeMethod.getReturnType()); + return aggregateAnnotation.getAttribute(attributeMethod.getName(), attributeMethod.getReturnType()); } /** diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AliasAnnotationPostProcessorTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AliasAnnotationPostProcessorTest.java index 922c3cc6b..b3af98d16 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/AliasAnnotationPostProcessorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AliasAnnotationPostProcessorTest.java @@ -57,6 +57,11 @@ public class AliasAnnotationPostProcessorTest { this.annotationMap = annotationMap; } + @Override + public Object getSource() { + return null; + } + @Override public SynthesizedAnnotationSelector getAnnotationSelector() { return null; @@ -68,7 +73,7 @@ public class AliasAnnotationPostProcessorTest { } @Override - public Collection getAnnotationAttributePostProcessors() { + public Collection getAnnotationPostProcessors() { return null; } @@ -78,7 +83,7 @@ public class AliasAnnotationPostProcessorTest { } @Override - public Collection getAllSynthesizedAnnotation() { + public Map, SynthesizedAnnotation> getAllSynthesizedAnnotation() { return null; } @@ -128,11 +133,6 @@ public class AliasAnnotationPostProcessorTest { } } - @Override - public SynthesizedAggregateAnnotation getOwner() { - return owner; - } - @Override public Object getRoot() { return null; diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessorTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessorTest.java index 877f8afb2..2521b2080 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/AliasLinkAnnotationPostProcessorTest.java @@ -85,6 +85,11 @@ public class AliasLinkAnnotationPostProcessorTest { this.annotationMap = annotationMap; } + @Override + public Object getSource() { + return null; + } + @Override public SynthesizedAnnotationSelector getAnnotationSelector() { return null; @@ -96,7 +101,7 @@ public class AliasLinkAnnotationPostProcessorTest { } @Override - public Collection getAnnotationAttributePostProcessors() { + public Collection getAnnotationPostProcessors() { return null; } @@ -106,7 +111,7 @@ public class AliasLinkAnnotationPostProcessorTest { } @Override - public Collection getAllSynthesizedAnnotation() { + public Map, SynthesizedAnnotation> getAllSynthesizedAnnotation() { return null; } @@ -156,11 +161,6 @@ public class AliasLinkAnnotationPostProcessorTest { } } - @Override - public SynthesizedAggregateAnnotation getOwner() { - return owner; - } - @Override public Object getRoot() { return null; diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/CacheableSynthesizedAnnotationAttributeProcessorTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/CacheableSynthesizedAnnotationAttributeProcessorTest.java index 3a9717134..4744866f7 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/CacheableSynthesizedAnnotationAttributeProcessorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/CacheableSynthesizedAnnotationAttributeProcessorTest.java @@ -38,11 +38,6 @@ public class CacheableSynthesizedAnnotationAttributeProcessorTest { this.value = value; } - @Override - public SynthesizedAggregateAnnotation getOwner() { - return null; - } - @Override public Object getRoot() { return null; diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessorTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessorTest.java index d14734229..3b422bb8d 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/MirrorLinkAnnotationPostProcessorTest.java @@ -59,6 +59,11 @@ public class MirrorLinkAnnotationPostProcessorTest { this.annotationMap = annotationMap; } + @Override + public Object getSource() { + return null; + } + @Override public SynthesizedAnnotationSelector getAnnotationSelector() { return null; @@ -70,7 +75,7 @@ public class MirrorLinkAnnotationPostProcessorTest { } @Override - public Collection getAnnotationAttributePostProcessors() { + public Collection getAnnotationPostProcessors() { return null; } @@ -80,7 +85,7 @@ public class MirrorLinkAnnotationPostProcessorTest { } @Override - public Collection getAllSynthesizedAnnotation() { + public Map, SynthesizedAnnotation> getAllSynthesizedAnnotation() { return null; } @@ -131,11 +136,6 @@ public class MirrorLinkAnnotationPostProcessorTest { } } - @Override - public SynthesizedAggregateAnnotation getOwner() { - return owner; - } - @Override public Object getRoot() { return null; diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/SynthesizedAnnotationSelectorTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/SynthesizedAnnotationSelectorTest.java index 0436d5c4c..0822fdb78 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/SynthesizedAnnotationSelectorTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/SynthesizedAnnotationSelectorTest.java @@ -87,11 +87,6 @@ public class SynthesizedAnnotationSelectorTest { this.horizontalDistance = horizontalDistance; } - @Override - public SynthesizedAggregateAnnotation getOwner() { - return null; - } - @Override public Object getRoot() { return null; diff --git a/hutool-core/src/test/java/cn/hutool/core/annotation/SyntheticMetaAnnotationTest.java b/hutool-core/src/test/java/cn/hutool/core/annotation/SyntheticMetaAnnotationTest.java index a0a279641..4b6d6c387 100644 --- a/hutool-core/src/test/java/cn/hutool/core/annotation/SyntheticMetaAnnotationTest.java +++ b/hutool-core/src/test/java/cn/hutool/core/annotation/SyntheticMetaAnnotationTest.java @@ -49,7 +49,7 @@ public class SyntheticMetaAnnotationTest { // 属性 Assert.assertEquals(SynthesizedAnnotationSelector.NEAREST_AND_OLDEST_PRIORITY, syntheticMetaAnnotation.getAnnotationSelector()); Assert.assertEquals(CacheableSynthesizedAnnotationAttributeProcessor.class, syntheticMetaAnnotation.getAnnotationAttributeProcessor().getClass()); - Assert.assertEquals(3, syntheticMetaAnnotation.getAnnotationAttributePostProcessors().size()); + Assert.assertEquals(3, syntheticMetaAnnotation.getAnnotationPostProcessors().size()); } @Test