添加层级对象接口

This commit is contained in:
huangchengxing 2022-07-14 16:16:14 +08:00
parent 18f67274b8
commit cf08a92f34
9 changed files with 284 additions and 40 deletions

View File

@ -22,14 +22,14 @@ import java.util.Comparator;
public class CacheableSynthesizedAnnotationAttributeProcessor implements SynthesizedAnnotationAttributeProcessor {
private final Table<String, Class<?>, Object> valueCaches = new RowKeyTable<>();
private final Comparator<SynthesizedAnnotation> annotationComparator;
private final Comparator<Hierarchical> annotationComparator;
/**
* 创建一个带缓存的注解值选择器
*
* @param annotationComparator 注解比较器排序更靠前的注解将被优先用于获取值
*/
public CacheableSynthesizedAnnotationAttributeProcessor(Comparator<SynthesizedAnnotation> annotationComparator) {
public CacheableSynthesizedAnnotationAttributeProcessor(Comparator<Hierarchical> annotationComparator) {
Assert.notNull(annotationComparator, "annotationComparator must not null");
this.annotationComparator = annotationComparator;
}
@ -40,7 +40,7 @@ public class CacheableSynthesizedAnnotationAttributeProcessor implements Synthes
* 越靠前的越优先被取值
*/
public CacheableSynthesizedAnnotationAttributeProcessor() {
this(SynthesizedAnnotation.DEFAULT_CHILD_PRIORITY_COMPARATOR);
this(Hierarchical.DEFAULT_HIERARCHICAL_COMPARATOR);
}
@SuppressWarnings("unchecked")

View File

@ -0,0 +1,155 @@
package cn.hutool.core.annotation;
import java.util.Comparator;
/**
* <p>描述以一个参照物为对象存在于该参照物的层级结构中的对象
*
* <p>该对象可通过{@link #getVerticalDistance()}{@link #getHorizontalDistance()}
* 描述其在以参照物为基点的坐标坐标系中的位置<br>
* 在需要对该接口的实现类进行按优先级排序时距离{@link #getRoot()}对象越近则该实现类的优先级越高
* 默认提供了{@link #DEFAULT_HIERARCHICAL_COMPARATOR}用于实现该比较规则<br>
* 一般情况下{@link #getRoot()}返回值相同的对象之间的比较才有意义
*
* <p>此外还提供了{@link Selector}接口用于根据一定的规则从两个{@link Hierarchical}实现类中选择并返回一个最合适的对象
* 默认提供了四个实现类
* <ul>
* <li>{@link Selector#NEAREST_AND_OLDEST_PRIORITY}: 返回距离根对象更近的对象当距离一样时优先返回旧对象</li>
* <li>{@link Selector#NEAREST_AND_NEWEST_PRIORITY}: 返回距离根对象更近的对象当距离一样时优先返回新对象</li>
* <li>{@link Selector#FARTHEST_AND_OLDEST_PRIORITY}: 返回距离根对象更远的对象当距离一样时优先返回旧对象</li>
* <li>{@link Selector#FARTHEST_AND_NEWEST_PRIORITY}: 返回距离根对象更远的对象当距离一样时优先返回新对象</li>
* </ul>
*
* @author huangchengxing
*/
public interface Hierarchical extends Comparable<Hierarchical> {
// ====================== compare ======================
/**
* 默认{@link #getHorizontalDistance()}{@link #getVerticalDistance()}排序的比较器
*/
Comparator<Hierarchical> DEFAULT_HIERARCHICAL_COMPARATOR = Comparator
.comparing(Hierarchical::getVerticalDistance)
.thenComparing(Hierarchical::getHorizontalDistance);
/**
* {@link #getVerticalDistance()}{@link #getHorizontalDistance()}排序
*
* @param o {@link SynthesizedAnnotation}对象
* @return 比较值
*/
@Override
default int compareTo(Hierarchical o) {
return DEFAULT_HIERARCHICAL_COMPARATOR.compare(this, o);
}
// ====================== hierarchical ======================
/**
* 参照物即坐标为{@code (0, 0)}的对象
* 当对象本身即为参照物时该方法应当返回其本身
*
* @return 参照物
*/
Object getRoot();
/**
* 获取该对象与参照物的垂直距离
* 默认情况下该距离即为当前对象与参照物之间相隔的层级数
*
* @return 合成注解与根对象的垂直距离
*/
int getVerticalDistance();
/**
* 获取该对象与参照物的水平距离
* 默认情况下该距离即为当前对象在与参照物{@link #getVerticalDistance()}相同的情况下条
* 该对象被扫描到的顺序
*
* @return 合成注解与根对象的水平距离
*/
int getHorizontalDistance();
// ====================== selector ======================
/**
* {@link Hierarchical}选择器用于根据一定的规则从两个{@link Hierarchical}实现类中选择并返回一个最合适的对象
*/
@FunctionalInterface
interface Selector {
/**
* 返回距离根对象更近的对象当距离一样时优先返回旧对象
*/
Selector NEAREST_AND_OLDEST_PRIORITY = new NearestAndOldestPrioritySelector();
/**
* 返回距离根对象更近的对象当距离一样时优先返回新对象
*/
Selector NEAREST_AND_NEWEST_PRIORITY = new NearestAndNewestPrioritySelector();
/**
* 返回距离根对象更远的对象当距离一样时优先返回旧对象
*/
Selector FARTHEST_AND_OLDEST_PRIORITY = new FarthestAndOldestPrioritySelector();
/**
* 返回距离根对象更远的对象当距离一样时优先返回新对象
*/
Selector FARTHEST_AND_NEWEST_PRIORITY = new FarthestAndNewestPrioritySelector();
/**
* 比较两个被合成的对象选择其中的一个并返回
*
* @param <T> 复合注解类型
* @param prev 上一对象该参数不允许为空
* @param next 下一对象该参数不允许为空
* @return 对象
*/
<T extends Hierarchical> T choose(T prev, T next);
/**
* 返回距离根对象更近的注解当距离一样时优先返回旧注解
*/
class NearestAndOldestPrioritySelector implements Selector {
@Override
public <T extends Hierarchical> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() < oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
}
}
/**
* 返回距离根对象更近的注解当距离一样时优先返回新注解
*/
class NearestAndNewestPrioritySelector implements Selector {
@Override
public <T extends Hierarchical> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() <= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
}
}
/**
* 返回距离根对象更远的注解当距离一样时优先返回旧注解
*/
class FarthestAndOldestPrioritySelector implements Selector {
@Override
public <T extends Hierarchical> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() > oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
}
}
/**
* 返回距离根对象更远的注解当距离一样时优先返回新注解
*/
class FarthestAndNewestPrioritySelector implements Selector {
@Override
public <T extends Hierarchical> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() >= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
}
}
}
}

View File

@ -34,7 +34,33 @@ import java.util.Collection;
* @see SynthesizedAnnotationPostProcessor
* @see SynthesizedMetaAggregateAnnotation
*/
public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnnotation {
public interface SynthesizedAggregateAnnotation extends Annotation, AggregateAnnotation, Hierarchical {
// ================== hierarchical ==================
/**
* 距离{@link #getRoot()}返回值的垂直距离
* 默认聚合注解即为根对象因此返回0
*
* @return 距离{@link #getRoot()}返回值的水平距离
*/
@Override
default int getVerticalDistance() {
return 0;
}
/**
* 距离{@link #getRoot()}返回值的水平距离
* 默认聚合注解即为根对象因此返回0
*
* @return 距离{@link #getRoot()}返回值的水平距离
*/
@Override
default int getHorizontalDistance() {
return 0;
}
// ================== synthesize ==================
/**
* 获取在聚合中存在的指定注解对象

View File

@ -3,7 +3,6 @@ package cn.hutool.core.annotation;
import cn.hutool.core.collection.CollUtil;
import java.lang.annotation.Annotation;
import java.util.Comparator;
import java.util.Map;
import java.util.function.UnaryOperator;
@ -16,16 +15,7 @@ import java.util.function.UnaryOperator;
* @author huangchengxing
* @see SynthesizedAggregateAnnotation
*/
public interface SynthesizedAnnotation extends Annotation, Comparable<SynthesizedAnnotation> {
/**
* {@link SynthesizedAnnotation}使用的默认的比较器
* 按照按{@link #getVerticalDistance()}{@link #getHorizontalDistance()}的返回值进行排序<br>
* 一般情况下排序越小的合成注解应当被优先处理
*/
Comparator<SynthesizedAnnotation> DEFAULT_CHILD_PRIORITY_COMPARATOR = Comparator
.comparing(SynthesizedAnnotation::getVerticalDistance)
.thenComparing(SynthesizedAnnotation::getHorizontalDistance);
public interface SynthesizedAnnotation extends Annotation, Hierarchical {
/**
* 获取所属的合成注解聚合器
@ -34,13 +24,6 @@ public interface SynthesizedAnnotation extends Annotation, Comparable<Synthesize
*/
SynthesizedAggregateAnnotation getOwner();
/**
* 获取该合成注解对应的根节点
*
* @return 合成注解对应的根节点
*/
Object getRoot();
/**
* 获取被合成的注解对象
*
@ -54,6 +37,7 @@ public interface SynthesizedAnnotation extends Annotation, Comparable<Synthesize
*
* @return 合成注解与根对象的垂直距离
*/
@Override
int getVerticalDistance();
/**
@ -62,6 +46,7 @@ public interface SynthesizedAnnotation extends Annotation, Comparable<Synthesize
*
* @return 合成注解与根对象的水平距离
*/
@Override
int getHorizontalDistance();
/**
@ -115,15 +100,4 @@ public interface SynthesizedAnnotation extends Annotation, Comparable<Synthesize
*/
Object getAttributeValue(String attributeName);
/**
* {@link #getVerticalDistance()}{@link #getHorizontalDistance()}排序
*
* @param o {@link SynthesizedAnnotation}对象
* @return 比较值
*/
@Override
default int compareTo(SynthesizedAnnotation o) {
return DEFAULT_CHILD_PRIORITY_COMPARATOR.compare(this, o);
}
}

View File

@ -45,7 +45,7 @@ public interface SynthesizedAnnotationSelector {
class NearestAndOldestPrioritySelector implements SynthesizedAnnotationSelector {
@Override
public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() < oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
return Hierarchical.Selector.NEAREST_AND_OLDEST_PRIORITY.choose(oldAnnotation, newAnnotation);
}
}
@ -55,7 +55,7 @@ public interface SynthesizedAnnotationSelector {
class NearestAndNewestPrioritySelector implements SynthesizedAnnotationSelector {
@Override
public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() <= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
return Hierarchical.Selector.NEAREST_AND_NEWEST_PRIORITY.choose(oldAnnotation, newAnnotation);
}
}
@ -65,7 +65,7 @@ public interface SynthesizedAnnotationSelector {
class FarthestAndOldestPrioritySelector implements SynthesizedAnnotationSelector {
@Override
public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() > oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
return Hierarchical.Selector.FARTHEST_AND_OLDEST_PRIORITY.choose(oldAnnotation, newAnnotation);
}
}
@ -75,7 +75,7 @@ public interface SynthesizedAnnotationSelector {
class FarthestAndNewestPrioritySelector implements SynthesizedAnnotationSelector {
@Override
public <T extends SynthesizedAnnotation> T choose(T oldAnnotation, T newAnnotation) {
return newAnnotation.getVerticalDistance() >= oldAnnotation.getVerticalDistance() ? newAnnotation : oldAnnotation;
return Hierarchical.Selector.FARTHEST_AND_NEWEST_PRIORITY.choose(oldAnnotation, newAnnotation);
}
}

View File

@ -52,6 +52,21 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
*/
private final Annotation source;
/**
* 根对象
*/
private final Object root;
/**
* 距离根对象的垂直距离
*/
private final int verticalDistance;
/**
* 距离根对象的水平距离
*/
private final int horizontalDistance;
/**
* 包含根注解以及其元注解在内的全部注解实例
*/
@ -94,11 +109,35 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
/**
* 基于指定根注解为其层级结构中的全部注解构造一个合成注解
*
* @param annotation 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param attributeProcessor 注解属性处理器
* @param annotation 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param attributeProcessor 注解属性处理器
* @param annotationPostProcessors 注解后置处理器
*/
public SynthesizedMetaAggregateAnnotation(
Annotation annotation,
SynthesizedAnnotationSelector annotationSelector,
SynthesizedAnnotationAttributeProcessor attributeProcessor,
Collection<? extends SynthesizedAnnotationPostProcessor> annotationPostProcessors) {
this(
null, 0, 0,
annotation, annotationSelector, attributeProcessor, annotationPostProcessors
);
}
/**
* 基于指定根注解为其层级结构中的全部注解构造一个合成注解
*
* @param root 根对象
* @param verticalDistance 距离根对象的水平距离
* @param horizontalDistance 距离根对象的垂直距离
* @param annotation 当前查找的注解对象
* @param annotationSelector 合成注解选择器
* @param attributeProcessor 注解属性处理器
* @param annotationPostProcessors 注解后置处理器
*/
SynthesizedMetaAggregateAnnotation(
Object root, int verticalDistance, int horizontalDistance,
Annotation annotation,
SynthesizedAnnotationSelector annotationSelector,
SynthesizedAnnotationAttributeProcessor attributeProcessor,
@ -108,6 +147,11 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
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;
@ -123,6 +167,36 @@ public class SynthesizedMetaAggregateAnnotation implements SynthesizedAggregateA
);
}
/**
* 获取根对象
*
* @return 根对象
*/
@Override
public Object getRoot() {
return root;
}
/**
* 获取与根对象的垂直距离
*
* @return 与根对象的垂直距离
*/
@Override
public int getVerticalDistance() {
return verticalDistance;
}
/**
* 获取与根对象的水平距离
*
* @return 获取与根对象的水平距离
*/
@Override
public int getHorizontalDistance() {
return horizontalDistance;
}
/**
* 获取根注解
*

View File

@ -106,6 +106,11 @@ public class AliasAnnotationPostProcessorTest {
public Object getAttribute(String attributeName, Class<?> attributeType) {
return null;
}
@Override
public Object getRoot() {
return null;
}
}
static class TestSynthesizedAnnotation implements SynthesizedAnnotation {

View File

@ -134,6 +134,11 @@ public class AliasLinkAnnotationPostProcessorTest {
public Object getAttribute(String attributeName, Class<?> attributeType) {
return null;
}
@Override
public Object getRoot() {
return null;
}
}
static class TestSynthesizedAnnotation implements SynthesizedAnnotation {

View File

@ -109,6 +109,11 @@ public class MirrorLinkAnnotationPostProcessorTest {
return null;
}
@Override
public Object getRoot() {
return null;
}
}
static class TestSynthesizedAnnotation implements SynthesizedAnnotation {