美文网首页
@SpringBootApplication中的三个注解

@SpringBootApplication中的三个注解

作者: 莫看烟雨 | 来源:发表于2018-08-11 13:25 被阅读0次

    本文基于springboot1.5.4版本。

    在springboot的世界中,有一个非常神奇的注解@SpringBootApplication,这个注解可以一键把你的工程变成springboot工程。

    下面我们来看下它的源码:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME) 
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication
    

    可以看出,SpringBootApplication是一个复合注解,其中重要的注解有ComponentScan,

    EnableAutoConfiguration和SpringBootConfiguration。其中SpringBootConfiguration其实是Configuration的简单封装,两者等价。

    使用上述三个注解代替@SpringBootApplication后,应用可以正常启动成功,完美!

    Configuration

    这个注解其实是spring的注解了,作用是替代xml格式的spring配置,不过多解释了。

    ComponentScan

    xml配置<context:component-scan/>的替代品。

    EnableAutoConfiguration

    @Import(EnableAutoConfigurationImportSelector.class)

    public @interface EnableAutoConfiguration

    这个是springboot的灵魂。EnableAutoConfiguration主要通过EnableAutoConfigurationImportSelector来实现具体功能。

    主要作用如下:

    1.通过SpringFactoriesLoader辅助类加载所有jar包里的/META-INF/spring.factories文件,

    查找其中的key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value。(其原理类似于java.util.ServiceLoader<E>,参考 ServiceLoader)。

    2.然后通过Conditonal下的一系列注解来过滤这些value中的类应不应该被加载。

    例如ConditionalOnClass/ConditionalOnProperty等。

    不过我有几个疑问一直没找到答案:

    1.Spring是如何处理这种复合注解的,如何识别一个注解上面还有其它的注解?

    2.ConditionalOnClass等条件的过滤是通过加载解析/META-INF/spring-autoconfigure-metadata.properties文件实现的,这个文件是自动解析类上的注解生成的吗,还是需要手动写?

    第一个疑问

    写了一段代码模拟spring解析annotation的操作:

    @Test
    
        public void testAnno(){
    
    TestAnno testAnno =new TestAnno();
    
    Class aClass = testAnno.getClass();
    
    //or this way
    
    //        aClass = TestAnno.class;
    
            Set set =new HashSet();
    
    for (Annotation annotation : aClass.getAnnotations()) {
    
    add2SetIter(set, annotation);
    
    }
    
    System.out.println(set);
    
    }
    
    private void add2SetIter(Set set, Annotation annotation) {
    
    set.add(annotation);
    
    for (Annotation annotation1 : annotation.annotationType().getAnnotations()) {
    
    if (BLACKLIST.contains(annotation1.annotationType())){
    
    continue;
    
    }
    
    add2SetIter(set, annotation1);
    
    }
    
    }
    
    private static final List>BLACKLIST = Arrays.asList(Documented.class,Retention.class,Target.class);
    

    第二个疑问

    添加以下依赖后,编译打包时会自动生成spring-autoconfigure-metadata.properties

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    

    2018-08-26更新,第一个疑问的答案

    org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.Class<?>, java.lang.Class<A>)
    

    相关文章

      网友评论

          本文标题:@SpringBootApplication中的三个注解

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