This commit is contained in:
Looly 2022-07-17 22:13:55 +08:00
parent 89dfeb5a76
commit ca10c8e7b9
6 changed files with 58 additions and 37 deletions

View File

@ -45,9 +45,9 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
final AnnotationAttribute linkedAttribute = linkedAnnotation.getAttributes().get(link.attribute()); final AnnotationAttribute linkedAttribute = linkedAnnotation.getAttributes().get(link.attribute());
// 处理 // 处理
processLinkedAttribute( processLinkedAttribute(
synthesizer, link, synthesizer, link,
synthesizedAnnotation, synthesizedAnnotation.getAttributes().get(originalAttributeName), synthesizedAnnotation, synthesizedAnnotation.getAttributes().get(originalAttributeName),
linkedAnnotation, linkedAttribute linkedAnnotation, linkedAttribute
); );
}); });
} }
@ -72,9 +72,9 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
* @param linkedAttribute {@link Link}指向的{@code originalAnnotation}中的关联属性该参数可能为空 * @param linkedAttribute {@link Link}指向的{@code originalAnnotation}中的关联属性该参数可能为空
*/ */
protected abstract void processLinkedAttribute( protected abstract void processLinkedAttribute(
AnnotationSynthesizer synthesizer, Link annotation, AnnotationSynthesizer synthesizer, Link annotation,
SynthesizedAnnotation originalAnnotation, AnnotationAttribute originalAttribute, SynthesizedAnnotation originalAnnotation, AnnotationAttribute originalAttribute,
SynthesizedAnnotation linkedAnnotation, AnnotationAttribute linkedAttribute SynthesizedAnnotation linkedAnnotation, AnnotationAttribute linkedAttribute
); );
// =========================== @Link注解的处理 =========================== // =========================== @Link注解的处理 ===========================
@ -88,9 +88,9 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
*/ */
protected Link getLinkAnnotation(AnnotationAttribute attribute, RelationType... relationTypes) { protected Link getLinkAnnotation(AnnotationAttribute attribute, RelationType... relationTypes) {
return Opt.ofNullable(attribute) return Opt.ofNullable(attribute)
.map(t -> AnnotationUtil.getSynthesizedAnnotation(attribute.getAttribute(), Link.class)) .map(t -> AnnotationUtil.getSynthesizedAnnotation(attribute.getAttribute(), Link.class))
.filter(a -> ArrayUtil.contains(relationTypes, a.type())) .filter(a -> ArrayUtil.contains(relationTypes, a.type()))
.get(); .get();
} }
/** /**
@ -98,9 +98,10 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
* *
* @param annotation {@link Link}注解 * @param annotation {@link Link}注解
* @param synthesizer 注解合成器 * @param synthesizer 注解合成器
* @param defaultType 默认类型
* @return {@link SynthesizedAnnotation}
*/ */
protected SynthesizedAnnotation getLinkedAnnotation( protected SynthesizedAnnotation getLinkedAnnotation(Link annotation, AnnotationSynthesizer synthesizer, Class<? extends Annotation> defaultType) {
Link annotation, AnnotationSynthesizer synthesizer, Class<? extends Annotation> defaultType) {
final Class<?> targetAnnotationType = getLinkedAnnotationType(annotation, defaultType); final Class<?> targetAnnotationType = getLinkedAnnotationType(annotation, defaultType);
return synthesizer.getSynthesizedAnnotation(targetAnnotationType); return synthesizer.getSynthesizedAnnotation(targetAnnotationType);
} }
@ -115,7 +116,7 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
*/ */
protected Class<?> getLinkedAnnotationType(Link annotation, Class<?> defaultType) { protected Class<?> getLinkedAnnotationType(Link annotation, Class<?> defaultType) {
return ObjectUtil.equals(annotation.annotation(), Annotation.class) ? return ObjectUtil.equals(annotation.annotation(), Annotation.class) ?
defaultType : annotation.annotation(); defaultType : annotation.annotation();
} }
// =========================== 注解属性的校验 =========================== // =========================== 注解属性的校验 ===========================
@ -128,17 +129,17 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
*/ */
protected void checkAttributeType(AnnotationAttribute original, AnnotationAttribute alias) { protected void checkAttributeType(AnnotationAttribute original, AnnotationAttribute alias) {
Assert.equals( Assert.equals(
original.getAttributeType(), alias.getAttributeType(), original.getAttributeType(), alias.getAttributeType(),
"return type of the linked attribute [{}] is inconsistent with the original [{}]", "return type of the linked attribute [{}] is inconsistent with the original [{}]",
original.getAttribute(), alias.getAttribute() original.getAttribute(), alias.getAttribute()
); );
} }
/** /**
* 检查{@link Link}指向的注解属性是否就是本身 * 检查{@link Link}指向的注解属性是否就是本身
* *
* @param original {@link Link}注解的属性 * @param original {@link Link}注解的属性
* @param linked {@link Link}指向的注解属性 * @param linked {@link Link}指向的注解属性
*/ */
protected void checkLinkedSelf(AnnotationAttribute original, AnnotationAttribute linked) { protected void checkLinkedSelf(AnnotationAttribute original, AnnotationAttribute linked) {
boolean linkSelf = (original == linked) || ObjectUtil.equals(original.getAttribute(), linked.getAttribute()); boolean linkSelf = (original == linked) || ObjectUtil.equals(original.getAttribute(), linked.getAttribute());
@ -154,8 +155,8 @@ public abstract class AbstractLinkAnnotationPostProcessor implements Synthesized
*/ */
protected void checkLinkedAttributeNotNull(AnnotationAttribute original, AnnotationAttribute linkedAttribute, Link annotation) { protected void checkLinkedAttributeNotNull(AnnotationAttribute original, AnnotationAttribute linkedAttribute, Link annotation) {
Assert.notNull(linkedAttribute, "cannot find linked attribute [{}] of original [{}] in [{}]", Assert.notNull(linkedAttribute, "cannot find linked attribute [{}] of original [{}] in [{}]",
original.getAttribute(), annotation.attribute(), original.getAttribute(), annotation.attribute(),
getLinkedAnnotationType(annotation, original.getAnnotationType()) getLinkedAnnotationType(annotation, original.getAnnotationType())
); );
} }

View File

@ -22,12 +22,16 @@ public @interface AliasFor {
/** /**
* 产生关联的注解类型当不指定时默认指注释的属性所在的类 * 产生关联的注解类型当不指定时默认指注释的属性所在的类
*
* @return 注解类型
*/ */
@Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR)
Class<? extends Annotation> annotation() default Annotation.class; Class<? extends Annotation> annotation() default Annotation.class;
/** /**
* {@link #annotation()}指定注解中关联的属性 * {@link #annotation()}指定注解中关联的属性
*
* @return 关联属性
*/ */
@Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR)
String attribute() default ""; String attribute() default "";

View File

@ -19,12 +19,16 @@ public @interface ForceAliasFor {
/** /**
* 产生关联的注解类型当不指定时默认指注释的属性所在的类 * 产生关联的注解类型当不指定时默认指注释的属性所在的类
*
* @return 关联注解类型
*/ */
@Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR)
Class<? extends Annotation> annotation() default Annotation.class; Class<? extends Annotation> annotation() default Annotation.class;
/** /**
* {@link #annotation()}指定注解中关联的属性 * {@link #annotation()}指定注解中关联的属性
*
* @return 关联的属性
*/ */
@Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR)
String attribute() default ""; String attribute() default "";

View File

@ -4,7 +4,7 @@ import java.lang.annotation.*;
/** /**
* <p>用于在同一注解中或具有一定关联的不同注解的属性中表明这些属性之间具有特定的关联关系 * <p>用于在同一注解中或具有一定关联的不同注解的属性中表明这些属性之间具有特定的关联关系
* 在通过{@link SynthesizedAggregateAnnotation}获取合成注解后合成注解获取属性值时会根据该注解进行调整<br /> * 在通过{@link SynthesizedAggregateAnnotation}获取合成注解后合成注解获取属性值时会根据该注解进行调整<br>
* *
* <p>该注解存在三个字注解{@link MirrorFor}{@link ForceAliasFor}{@link AliasFor} * <p>该注解存在三个字注解{@link MirrorFor}{@link ForceAliasFor}{@link AliasFor}
* 使用三个子注解等同于{@link Link}但是需要注意的是 * 使用三个子注解等同于{@link Link}但是需要注意的是
@ -27,16 +27,22 @@ public @interface Link {
/** /**
* 产生关联的注解类型当不指定时默认指注释的属性所在的类 * 产生关联的注解类型当不指定时默认指注释的属性所在的类
*
* @return 关联的注解类型
*/ */
Class<? extends Annotation> annotation() default Annotation.class; Class<? extends Annotation> annotation() default Annotation.class;
/** /**
* {@link #annotation()}指定注解中关联的属性 * {@link #annotation()}指定注解中关联的属性
*
* @return 属性名
*/ */
String attribute() default ""; String attribute() default "";
/** /**
* {@link #attribute()}指定属性与当前注解的属性建的关联关系类型 * {@link #attribute()}指定属性与当前注解的属性建的关联关系类型
*
* @return 关系类型
*/ */
RelationType type() default RelationType.MIRROR_FOR; RelationType type() default RelationType.MIRROR_FOR;

View File

@ -25,12 +25,16 @@ public @interface MirrorFor {
/** /**
* 产生关联的注解类型当不指定时默认指注释的属性所在的类 * 产生关联的注解类型当不指定时默认指注释的属性所在的类
*
* @return 关联的注解类型
*/ */
@Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "annotation", type = RelationType.FORCE_ALIAS_FOR)
Class<? extends Annotation> annotation() default Annotation.class; Class<? extends Annotation> annotation() default Annotation.class;
/** /**
* {@link #annotation()}指定注解中关联的属性 * {@link #annotation()}指定注解中关联的属性
*
* @return 属性名
*/ */
@Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR) @Link(annotation = Link.class, attribute = "attribute", type = RelationType.FORCE_ALIAS_FOR)
String attribute() default ""; String attribute() default "";

View File

@ -34,6 +34,7 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
/** /**
* 创建一个代理注解生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类 * 创建一个代理注解生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类
* *
* @param <T> 注解类型
* @param annotationType 注解类型 * @param annotationType 注解类型
* @param annotationAttributeValueProvider 注解属性值获取器 * @param annotationAttributeValueProvider 注解属性值获取器
* @param annotation 合成注解 * @param annotation 合成注解
@ -41,9 +42,9 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T extends Annotation> T create( public static <T extends Annotation> T create(
Class<T> annotationType, Class<T> annotationType,
AnnotationAttributeValueProvider annotationAttributeValueProvider, AnnotationAttributeValueProvider annotationAttributeValueProvider,
SynthesizedAnnotation annotation) { SynthesizedAnnotation annotation) {
if (ObjectUtil.isNull(annotation)) { if (ObjectUtil.isNull(annotation)) {
return null; return null;
} }
@ -52,26 +53,27 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
return null; return null;
} }
return (T) Proxy.newProxyInstance( return (T) Proxy.newProxyInstance(
annotationType.getClassLoader(), annotationType.getClassLoader(),
new Class[]{annotationType, SyntheticProxyAnnotation.class}, new Class[]{annotationType, SyntheticProxyAnnotation.class},
proxyHandler proxyHandler
); );
} }
/** /**
* 创建一个代理注解生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类 * 创建一个代理注解生成的代理对象将是{@link SyntheticProxyAnnotation}与指定的注解类的子类
* *
* @param <T> 注解类型
* @param annotationType 注解类型 * @param annotationType 注解类型
* @param annotation 合成注解 * @param annotation 合成注解
* @return 代理注解 * @return 代理注解
*/ */
public static <T extends Annotation> T create( public static <T extends Annotation> T create(
Class<T> annotationType, SynthesizedAnnotation annotation) { Class<T> annotationType, SynthesizedAnnotation annotation) {
return create(annotationType, annotation, annotation); return create(annotationType, annotation, annotation);
} }
/** /**
* 该类是否为通过{@link SynthesizedAnnotationProxy}生成的代理类 * 该类是否为通过{@code SynthesizedAnnotationProxy}生成的代理类
* *
* @param annotationType 注解类型 * @param annotationType 注解类型
* @return 是否 * @return 是否
@ -92,8 +94,8 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
@Override @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return Opt.ofNullable(methods.get(method.getName())) return Opt.ofNullable(methods.get(method.getName()))
.map(m -> m.apply(method, args)) .map(m -> m.apply(method, args))
.orElseGet(() -> ReflectUtil.invoke(this, method, args)); .orElseGet(() -> ReflectUtil.invoke(this, method, args));
} }
// ========================= 代理方法 ========================= // ========================= 代理方法 =========================
@ -105,12 +107,12 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
methods.put("getRoot", (method, args) -> annotation.getRoot()); methods.put("getRoot", (method, args) -> annotation.getRoot());
methods.put("getVerticalDistance", (method, args) -> annotation.getVerticalDistance()); methods.put("getVerticalDistance", (method, args) -> annotation.getVerticalDistance());
methods.put("getHorizontalDistance", (method, args) -> annotation.getHorizontalDistance()); methods.put("getHorizontalDistance", (method, args) -> annotation.getHorizontalDistance());
methods.put("hasAttribute", (method, args) -> annotation.hasAttribute((String)args[0], (Class<?>)args[1])); methods.put("hasAttribute", (method, args) -> annotation.hasAttribute((String) args[0], (Class<?>) args[1]));
methods.put("getAttributes", (method, args) -> annotation.getAttributes()); methods.put("getAttributes", (method, args) -> annotation.getAttributes());
methods.put("setAttribute", (method, args) -> { methods.put("setAttribute", (method, args) -> {
throw new UnsupportedOperationException("proxied annotation can not reset attributes"); throw new UnsupportedOperationException("proxied annotation can not reset attributes");
}); });
methods.put("getAttributeValue", (method, args) -> annotation.getAttributeValue((String)args[0])); methods.put("getAttributeValue", (method, args) -> annotation.getAttributeValue((String) args[0]));
methods.put("annotationType", (method, args) -> annotation.annotationType()); methods.put("annotationType", (method, args) -> annotation.annotationType());
for (final Method declaredMethod : ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType())) { for (final Method declaredMethod : ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType())) {
methods.put(declaredMethod.getName(), (method, args) -> proxyAttributeValue(method)); methods.put(declaredMethod.getName(), (method, args) -> proxyAttributeValue(method));
@ -119,11 +121,11 @@ public class SynthesizedAnnotationProxy implements InvocationHandler {
private String proxyToString() { private String proxyToString() {
final String attributes = Stream.of(ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType())) final String attributes = Stream.of(ClassUtil.getDeclaredMethods(annotation.getAnnotation().annotationType()))
.filter(AnnotationUtil::isAttributeMethod) .filter(AnnotationUtil::isAttributeMethod)
.map(method -> CharSequenceUtil.format( .map(method -> CharSequenceUtil.format(
"{}={}", method.getName(), proxyAttributeValue(method)) "{}={}", method.getName(), proxyAttributeValue(method))
) )
.collect(Collectors.joining(", ")); .collect(Collectors.joining(", "));
return CharSequenceUtil.format("@{}({})", annotation.annotationType().getName(), attributes); return CharSequenceUtil.format("@{}({})", annotation.annotationType().getName(), attributes);
} }