@SpringBootApplication中的三个注解

本文基于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配置的替代品。

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,参考 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


    org.springframework.boot
    spring-boot-configuration-processor
    true

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

org.springframework.core.annotation.AnnotationUtils#findAnnotation(java.lang.Class, java.lang.Class)

你可能感兴趣的:(@SpringBootApplication中的三个注解)