Class AnnotatedElements

java.lang.Object
org.miaixz.bus.core.lang.annotation.resolve.AnnotatedElements

public class AnnotatedElements extends Object
AnnotatedElement工具类,提供对层级结构中AnnotatedElement上注解及元注解的访问支持, 并提供诸如基于Alias的属性别名、基于父子注解间的属性值覆盖等特殊的属性映射机制支持。 搜索层级结构 参考 Spring 中AnnotatedElementUtils, 工具类提供get以及find两种语义的搜索:
  • get:表示搜索范围仅限于指定的AnnotatedElement本身;
  • find:表示搜索范围除了指定的AnnotatedElement本身外, 若AnnotatedElement是类,则还会搜索其所有关联的父类和父接口; 若AnnotatedElement是方法,则还会搜索其声明类关联的所有父类和父接口中,与该方法具有相同方法签名的方法对象;
eg: 若类A分别有父类和父接口BC, 则通过getXXX方法将只能获得A上的注解, 而通过findXXX方法将能获得ABC上的注解。 搜索元注解 工具类支持搜索注解的元注解。在所有格式为getXXXfindXXX的静态方法中, 若不带有directly关键字,则该方法支持搜索元注解,否则不支持搜索元注解。 eg: 若类A分别有父类和父接口BC,上面分别有注解X与其元注解Y, 则此时基于A有:
  • getDirectlyXXX:能够获得A上的注解X
  • getXXX:能够获得A上的注解X及元注解Y
  • findDirectlyXXX:能够分别获得ABC上的注解X
  • findXXX:能够分别获得ABC上的注解X及元注解Y
注意:在当前实例中将无视Inherited的效果,即通过directly方法将无法获得父类上带有Inherited的注解。 注解属性映射 工具类支持注解对象属性上的一些属性映射机制,即当注解被扫描时, 将根据一些属性映射机制“解析”为其他类型的属性,这里支持的机制包括:
  • 基于Alias的属性别名:若注解属性通过Alias互相关联,则对其中任意属性赋值,则等同于对所有关联属性赋值; eg:
    
              // set aliased attributes
             @interface FooAnnotation {
                 @Alias("alias")
                  default String value() default "";
                 @Alias("value")
                  default String alias() default "";
              }
             @FooAnnotation("foo")
              class Foo { }
    
              // get resolved annotation
              FooAnnotation annotation = getResolvedAnnotation(Foo.class, FooAnnotation.class);
              annotation.value(); // = "foo"
              annotation.alias(); // = "foo"
             }
  • 基于父子注解的属性覆写:若子注解中存在属性,与其元注解的属性名称、类型皆相同,则子注解的属性值将会覆写其元注解的属性值, 若被覆写的属性值存在关联别名,则关联别名也会被一并覆写。 eg:
    
             @interface Meta {
                  default String value() default "";
              }
             @Meta("meta")
              @interface Root {
                  default String value() default ""; // overwrite for @Meta.value
              }
             @Root("foo")
              class Foo { }
    
              // get resolved annotation
              Meta meta = getResolvedAnnotation(Foo.class, Meta.class);
              meta.value(); // = "foo"
              Root root = getResolvedAnnotation(Foo.class, Root.class);
              root.value(); // = "foo"
             
可重复注解支持 工具类中格式为findAllXXXgetAllXXX格式的方法, 支持获得AnnotatedElement上的可重复注解。 此处的可重复注解定义包括两方面:
  • AnnotatedElement存在直接声明的注解,该注解有且仅有一个value属性, 该属性类型为注解数组,且数组中注解被Repeatable注解, 则认为被包括的注解为可重复注解; eg: A上存在注解X,该注解是一个容器注解,内部包含可重复注解Y, 解析X后,得到注解X与它包含的可重复注解Y
  • AnnotatedElement存在直接声明的注解,该注解与其他根注解皆有相同的元注解, 则获得元注解时,可以获得多个该相同的元注解。 eg: A上存在注解XY,两者皆有元注解Z, 则通过AnnotatedElement可以获得两个Z
缓存 为了避免注解以及AnnotatedElement层级结构解析过程中的大量反射调用, 工具类为AnnotatedElement及其元注解信息进行了缓存。 缓存功能默认基于WeakConcurrentMap实现,会在gc时自动回收部分缓存数据。 但是若有必要,也可以调用clearCaches()方法主动清空缓存。
Since:
Java 17+
Author:
Kimi Liu
See Also: