提取注解合成相关逻辑至注解合成器

This commit is contained in:
huangchengxing 2022-07-16 13:18:55 +08:00
parent cf08a92f34
commit 931965301b
18 changed files with 331 additions and 254 deletions

View File

@ -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<T> implements AnnotationSynthesizer {
/**
* 合成注解来源最初来源
*/
protected final T source;
/**
* 包含根注解以及其元注解在内的全部注解实例
*/
protected final Map<Class<? extends Annotation>, SynthesizedAnnotation> synthesizedAnnotationMap;
/**
* 合成注解选择器
*/
protected final SynthesizedAnnotationSelector annotationSelector;
/**
* 合成注解属性处理器
*/
protected final Collection<SynthesizedAnnotationPostProcessor> postProcessors;
/**
* 基于指定根注解为其层级结构中的全部注解构造一个合成注解
*
* @param source 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param annotationPostProcessors 注解后置处理器
*/
protected AbstractAnnotationSynthesizer(
T source, SynthesizedAnnotationSelector annotationSelector, Collection<SynthesizedAnnotationPostProcessor> 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<Class<? extends Annotation>, SynthesizedAnnotation> loadAnnotations();
/**
* 根据指定的注解类型和对应注解对象合成最终所需的合成注解
*
* @param annotationType 注解类型
* @param annotation 合成注解对象
* @param <A> 注解类型
* @return 最终所需的合成注解
*/
protected abstract <A extends Annotation> A synthesize(Class<A> annotationType, SynthesizedAnnotation annotation);
/**
* 获取合成注解来源最初来源
*
* @return 合成注解来源最初来源
*/
@Override
public T getSource() {
return source;
}
/**
* 合成注解选择器
*
* @return 注解选择器
*/
@Override
public SynthesizedAnnotationSelector getAnnotationSelector() {
return annotationSelector;
}
/**
* 获取合成注解后置处理器
*
* @return 合成注解后置处理器
*/
@Override
public Collection<SynthesizedAnnotationPostProcessor> getAnnotationPostProcessors() {
return postProcessors;
}
/**
* 获取已合成的注解
*
* @param annotationType 注解类型
* @return 已合成的注解
*/
@Override
public SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType) {
return synthesizedAnnotationMap.get(annotationType);
}
/**
* 获取全部的合成注解
*
* @return 合成注解
*/
@Override
public Map<Class<? extends Annotation>, SynthesizedAnnotation> getAllSynthesizedAnnotation() {
return synthesizedAnnotationMap;
}
/**
* 获取合成注解
*
* @param annotationType 注解类型
* @param <A> 注解类型
* @return 类型
*/
@Override
public <A extends Annotation> A synthesize(Class<A> annotationType) {
SynthesizedAnnotation synthesizedAnnotation = synthesizedAnnotationMap.get(annotationType);
if (ObjectUtil.isNull(synthesizedAnnotation)) {
return null;
}
return synthesize(annotationType, synthesizedAnnotation);
}
}

View File

@ -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<String, AnnotationAttribute> 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<? extends Annotation> defaultType) {
Link annotation, AnnotationSynthesizer synthesizer, Class<? extends Annotation> defaultType) {
final Class<?> targetAnnotationType = getLinkedAnnotationType(annotation, defaultType);
return synthesizedAnnotationAggregator.getSynthesizedAnnotation(targetAnnotationType);
return synthesizer.getSynthesizedAnnotation(targetAnnotationType);
}
/**

View File

@ -20,7 +20,6 @@ import java.util.stream.Stream;
*/
public abstract class AbstractSynthesizedAnnotation<R> implements Annotation, SynthesizedAnnotation {
private final SynthesizedAggregateAnnotation owner;
private final R root;
private final Annotation annotation;
private final Map<String, AnnotationAttribute> attributeMethodCaches;
@ -30,15 +29,13 @@ public abstract class AbstractSynthesizedAnnotation<R> 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<R> implements Annotation, Sy
.get();
}
/**
* 获取所属的合成注解集合器
*
* @return 合成注解
*/
@Override
public SynthesizedAggregateAnnotation getOwner() {
return owner;
}
/**
* 获取该合成注解对应的根节点
*

View File

@ -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<String, AnnotationAttribute> attributeMap = synthesizedAnnotation.getAttributes();
// 记录别名与属性的关系

View File

@ -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<AnnotationAttribute> wrapping) {
AnnotationSynthesizer synthesizer, AnnotationAttribute originalAttribute, AnnotationAttribute aliasAttribute, BinaryOperator<AnnotationAttribute> 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<AnnotationAttribute> wrapping) {
Opt.ofNullable(target.getAnnotationType())
.map(synthesizedAnnotationAggregator::getSynthesizedAnnotation)
.map(synthesizer::getSynthesizedAnnotation)
.ifPresent(t -> t.replaceAttribute(target.getAttributeName(), old -> wrapping.apply(old, originalAttribute)));
}

View File

@ -0,0 +1,77 @@
package cn.hutool.core.annotation;
import java.lang.annotation.Annotation;
import java.util.Collection;
import java.util.Map;
/**
* <p>注解合成器用于处理一组给定的与{@link #getSource()}具有直接或间接联系的注解对象
* 并返回与原始注解对象具有不同属性的合成注解
*
* <p>合成注解一般被用于处理类层级结果中具有直接或间接关联的注解对象
* 当实例被创建时会获取到这些注解对象并使用{@link SynthesizedAnnotationSelector}对类型相同的注解进行过滤
* 并最终得到类型不重复的有效注解对象这些有效注解将被包装为{@link SynthesizedAnnotation}
* 然后最终用于合成一个{@link SynthesizedAggregateAnnotation}<br>
* {@link SynthesizedAnnotationSelector}是合成注解生命周期中的第一个钩子
* 自定义选择器以拦截原始注解被扫描的过程
*
* <p>当合成注解完成对待合成注解的扫描并完成了必要属性的加载后
* 将会按顺序依次调用{@link SynthesizedAnnotationPostProcessor}
* 注解后置处理器允许用于对完成注解的待合成注解进行二次调整
* 该钩子一般用于根据{@link Link}注解对属性进行调整<br>
* {@link SynthesizedAnnotationPostProcessor}是合成注解生命周期中的第二个钩子
* 自定义后置处理器以拦截原始在转为待合成注解后的初始化过程
*
* <p>使用{@link #synthesize(Class)}用于获取合成后的注解
* 该注解对象的属性可能会与原始的对象属性不同
*
* @author huangchengxing
*/
public interface AnnotationSynthesizer {
/**
* 获取合成注解来源最初来源
*
* @return 合成注解来源最初来源
*/
Object getSource();
/**
* 合成注解选择器
*
* @return 注解选择器
*/
SynthesizedAnnotationSelector getAnnotationSelector();
/**
* 获取合成注解后置处理器
*
* @return 合成注解后置处理器
*/
Collection<SynthesizedAnnotationPostProcessor> getAnnotationPostProcessors();
/**
* 获取已合成的注解
*
* @param annotationType 注解类型
* @return 已合成的注解
*/
SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType);
/**
* 获取全部的合成注解
*
* @return 合成注解
*/
Map<Class<? extends Annotation>, SynthesizedAnnotation> getAllSynthesizedAnnotation();
/**
* 获取合成注解
*
* @param annotationType 注解类型
* @param <T> 注解类型
* @return 类型
*/
<T extends Annotation> T synthesize(Class<T> annotationType);
}

View File

@ -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;
/**
* <p>用于处理注解对象中带有{@link Link}注解{@link Link#type()}{@link RelationType#MIRROR_FOR}的属性<br>
@ -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(),

View File

@ -1,10 +1,10 @@
package cn.hutool.core.annotation;
import java.lang.annotation.Annotation;
import java.util.Collection;
/**
* 表示基于特定规则聚合将一组注解聚合而来的注解对象
* <p>表示基于特定规则聚合将一组注解聚合而来的注解对象
* 该注解对象允许根据一定规则合成一些跟原始注解属性不一样合成注解
*
* <p>合成注解一般被用于处理类层级结果中具有直接或间接关联的注解对象
* 当实例被创建时会获取到这些注解对象并使用{@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 extends Annotation> T getAnnotation(Class<T> annotationType);
/**
* 获取合成注解选择器
*
* @return 合成注解选择器
*/
SynthesizedAnnotationSelector getAnnotationSelector();
/**
* 获取合成注解属性处理器
*
@ -85,28 +79,6 @@ public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnn
*/
SynthesizedAnnotationAttributeProcessor getAnnotationAttributeProcessor();
/**
* 获取合成注解属性后置处理器
*
* @return 合成注解属性后置处理器
*/
Collection<SynthesizedAnnotationPostProcessor> getAnnotationAttributePostProcessors();
/**
* 获取已合成的注解
*
* @param annotationType 注解类型
* @return 已合成的注解
*/
SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType);
/**
* 获取全部的合成注解
*
* @return 合成注解
*/
Collection<SynthesizedAnnotation> getAllSynthesizedAnnotation();
/**
* 获取当前的注解类型
*
@ -126,15 +98,6 @@ public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnn
*/
Object getAttribute(String attributeName, Class<?> attributeType);
/**
* 获取合成注解
*
* @param annotationType 注解类型
* @param <T> 注解类型
* @return 类型
*/
<T extends Annotation> T synthesize(Class<T> annotationType);
/**
* 基于指定根注解构建包括其元注解在内的合成注解
*

View File

@ -8,7 +8,7 @@ import java.util.function.UnaryOperator;
/**
* <p>用于在{@link SynthesizedAggregateAnnotation}中表示一个处于合成状态的注解对象<br>
* 当对多个合成注解排序时默认使用{@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();
/**
* 获取被合成的注解对象
*

View File

@ -64,8 +64,8 @@ public interface SynthesizedAnnotationPostProcessor extends Comparable<Synthesiz
* 给定指定被合成注解与其所属的合成注解聚合器实例经过处理后返回最终
*
* @param synthesizedAnnotation 合成的注解
* @param aggregator 合成注解聚合
* @param synthesizer 注解合成
*/
void process(SynthesizedAnnotation synthesizedAnnotation, SynthesizedAggregateAnnotation aggregator);
void process(SynthesizedAnnotation synthesizedAnnotation, AnnotationSynthesizer synthesizer);
}

View File

@ -7,7 +7,10 @@ import cn.hutool.core.util.ObjectUtil;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* {@link SynthesizedAggregateAnnotation}的基本实现表示一个根注解与根注解上的多层元注解的聚合得到的注解
@ -45,12 +48,7 @@ import java.util.*;
* @see AnnotationUtil
* @see SynthesizedAnnotationSelector
*/
public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateAnnotation {
/**
* 根注解即当前查找的注解
*/
private final Annotation source;
public class SynthesizedMetaAggregateAnnotation extends AbstractAnnotationSynthesizer<Annotation> implements SynthesizedAggregateAnnotation {
/**
* 根对象
@ -67,26 +65,11 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
*/
private final int horizontalDistance;
/**
* 包含根注解以及其元注解在内的全部注解实例
*/
private final Map<Class<? extends Annotation>, SynthesizedAnnotation> metaAnnotationMap;
/**
* 合成注解选择器
*/
private final SynthesizedAnnotationSelector annotationSelector;
/**
* 合成注解属性处理器
*/
private final SynthesizedAnnotationAttributeProcessor attributeProcessor;
/**
* 合成注解属性处理器
*/
private final List<SynthesizedAnnotationPostProcessor> postProcessors;
/**
* 基于指定根注解为其层级结构中的全部注解构造一个合成注解
* 当层级结构中出现了相同的注解对象时将优先选择以距离根注解最近且优先被扫描的注解对象,
@ -118,7 +101,7 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
Annotation annotation,
SynthesizedAnnotationSelector annotationSelector,
SynthesizedAnnotationAttributeProcessor attributeProcessor,
Collection<? extends SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
Collection<SynthesizedAnnotationPostProcessor> 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<? extends SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
Assert.notNull(annotation, "annotation must not null");
Assert.notNull(annotationSelector, "annotationSelector must not null");
Collection<SynthesizedAnnotationPostProcessor> 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<Class<? extends Annotation>, SynthesizedAnnotation> loadAnnotations() {
Assert.isFalse(SyntheticAnnotationProxy.isProxyAnnotation(source.getClass()), "source [{}] has been synthesized");
Map<Class<? extends Annotation>, 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<SynthesizedAnnotationPostProcessor> getAnnotationAttributePostProcessors() {
return this.postProcessors;
}
/**
* 获取已合成的注解
*
* @param annotationType 注解类型
* @return 已合成的注解
*/
@Override
public SynthesizedAnnotation getSynthesizedAnnotation(Class<?> annotationType) {
return metaAnnotationMap.get(annotationType);
}
/**
* 获取全部的已合成注解
*
* @return 合成注解
*/
@Override
public Collection<SynthesizedAnnotation> getAllSynthesizedAnnotation() {
return metaAnnotationMap.values();
}
/**
* 根据指定的属性名与属性类型获取对应的属性值若存在{@link Alias}则获取{@link Alias#value()}指定的别名属性的值
* <p>当不同层级的注解之间存在同名同类型属性时将优先获取更接近根注解的属性
@ -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 extends Annotation> T getAnnotation(Class<T> 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<? extends Annotation> 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 extends Annotation> T synthesize(Class<T> 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 extends Annotation> T synthesize(Class<T> 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);
}
}

View File

@ -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<String, BiFunction<Method, Object[], Object>> 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 {
* </ul>
*
* @param annotationType 注解类型
* @param synthesizedAnnotationAggregator 合成注解
* @param aggregateAnnotation 合成注解
* @return 代理注解
*/
@SuppressWarnings("unchecked")
static <T extends Annotation> T create(
Class<T> annotationType, SynthesizedAggregateAnnotation synthesizedAnnotationAggregator) {
final SynthesizedAnnotation annotation = synthesizedAnnotationAggregator.getSynthesizedAnnotation(annotationType);
Class<T> 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());
}
/**

View File

@ -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<SynthesizedAnnotationPostProcessor> getAnnotationAttributePostProcessors() {
public Collection<SynthesizedAnnotationPostProcessor> getAnnotationPostProcessors() {
return null;
}
@ -78,7 +83,7 @@ public class AliasAnnotationPostProcessorTest {
}
@Override
public Collection<SynthesizedAnnotation> getAllSynthesizedAnnotation() {
public Map<Class<? extends Annotation>, SynthesizedAnnotation> getAllSynthesizedAnnotation() {
return null;
}
@ -128,11 +133,6 @@ public class AliasAnnotationPostProcessorTest {
}
}
@Override
public SynthesizedAggregateAnnotation getOwner() {
return owner;
}
@Override
public Object getRoot() {
return null;

View File

@ -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<SynthesizedAnnotationPostProcessor> getAnnotationAttributePostProcessors() {
public Collection<SynthesizedAnnotationPostProcessor> getAnnotationPostProcessors() {
return null;
}
@ -106,7 +111,7 @@ public class AliasLinkAnnotationPostProcessorTest {
}
@Override
public Collection<SynthesizedAnnotation> getAllSynthesizedAnnotation() {
public Map<Class<? extends Annotation>, SynthesizedAnnotation> getAllSynthesizedAnnotation() {
return null;
}
@ -156,11 +161,6 @@ public class AliasLinkAnnotationPostProcessorTest {
}
}
@Override
public SynthesizedAggregateAnnotation getOwner() {
return owner;
}
@Override
public Object getRoot() {
return null;

View File

@ -38,11 +38,6 @@ public class CacheableSynthesizedAnnotationAttributeProcessorTest {
this.value = value;
}
@Override
public SynthesizedAggregateAnnotation getOwner() {
return null;
}
@Override
public Object getRoot() {
return null;

View File

@ -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<SynthesizedAnnotationPostProcessor> getAnnotationAttributePostProcessors() {
public Collection<SynthesizedAnnotationPostProcessor> getAnnotationPostProcessors() {
return null;
}
@ -80,7 +85,7 @@ public class MirrorLinkAnnotationPostProcessorTest {
}
@Override
public Collection<SynthesizedAnnotation> getAllSynthesizedAnnotation() {
public Map<Class<? extends Annotation>, SynthesizedAnnotation> getAllSynthesizedAnnotation() {
return null;
}
@ -131,11 +136,6 @@ public class MirrorLinkAnnotationPostProcessorTest {
}
}
@Override
public SynthesizedAggregateAnnotation getOwner() {
return owner;
}
@Override
public Object getRoot() {
return null;

View File

@ -87,11 +87,6 @@ public class SynthesizedAnnotationSelectorTest {
this.horizontalDistance = horizontalDistance;
}
@Override
public SynthesizedAggregateAnnotation getOwner() {
return null;
}
@Override
public Object getRoot() {
return null;

View File

@ -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