美文网首页
Spring元注解应用

Spring元注解应用

作者: 随风摇摆水杉树 | 来源:发表于2021-12-26 13:13 被阅读0次

一、Spring元注解

Spring有很多注解类型,有些是元注解,有些是派生注解,比如:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}

@Service是被@Component注解的,而@Component是Spring提供的元注解,因此@Service也具有将一个类标记为Spring Bean的能力。

二、Spring处理派生注解的方式

首先定义个派生注解,并且应用该注解,方便通过DBUG来分析Spring源代码:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface MyConfigurationAnnotation {
}

@MyConfigurationAnnotation
public class MyConfiguration {

}

@Configuration为例,该注解会被ConfigurationClassPostProcessor#processConfigBeanDefinitions方法所解析:

configuration的处理方法.png
该方法又通过ConfigurationClassUtils#checkConfigurationClassCandidate来处理。 查找是否被Configuration所注解.png
metadata是一个AnnotationMetadata实例,下面看下AnnotationMetadata的继承关系:
AnnotationMetadata继承关系.png
metadata.getAnnotationAttributes(Configuration.class.getName())通过层层调用最终会定位到AnnotatedTypeMetadata#getAnnotationAttributes(String annotationName, boolean classValuesAsString)方法:
AnnotatedTypeMetaData.png

到目前为止还是无法了解Spring是如何查找注解的,但是还是看到了一个get方法,所以只能硬着头皮继续往下找,通过DEBUG发现它调用的是MergedAnnotationsCollection#get,经过跳转最终在MergedAnnotationsCollection#find方法中找到了关键代码:

判断是否拥有请求的注解.png

以前面定义的MyConfiguration为例,它被自定义的@MyConfigurationAnnotation所注解,mappings会存储所有的@MyConfigurationAnnotation注解包括@Configuration@Component@Indexed,所有注解的注解都会包括进来。这样当查询@Configuration注解是否在类MyConfiguration上定义时就能返回指定的信息,自定义的@MyConfigurationAnnotation具有了跟@Configuration一样的能力。

Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());

到目前为止Spring是如何让派生注解拥有元注解的能力已经了解的差不多了,但是还有一个小疑问就是this.mappings[]数组是哪里生成的,它是如何将所有的注解收集起来的。很幸运在MergedAnnotationsCollection构造方法中找到了关键代码行:

MergedAnnotationsCollection构造方法.png
forAnnotationType.png
forAnnotationType2.png
Cache.png AnnotationTypeMapping.png

经过来回跳转终于在AnnotationTypeMappings类中看到了关键代码:

addMetaAnnotationsToQueue.png
Spring就是这样不断循环查找注解的注解来收集所有的已声明的注解。

至于@MyConfigurationAnnotation是哪里读取的,可以看下ClassReader583行以及SimpleAnnotationMetadataReadingVisitor119行

相关文章

网友评论

      本文标题:Spring元注解应用

      本文链接:https://www.haomeiwen.com/subject/sdtsqrtx.html