@SpringBootApplication
- 是一个“三体”结构
- 实际上它是一个复合 Annotation
元注解(meta-annotation):
- 是指负责注解其他注解的注解
- JDK 1.5及以后版本定义了4个标准的元注解类型
简单介绍一下:
- @Target:通过ElementType来指定注解可使用范围
- @Retention:通过RetentionPolicy来指定注解的生命周期
- @Documented:标记注解,用于描述其它类型的注解应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具 文档化。
- @Inherited:标记注解,允许子类继承父类
虽然@SpringBootApplication的定义使用了多个 Annotation 进行元信息标注
但实际上对于 SpringBoot 应用来说,重要的只有三个 Annotation
而“三体”结构实际上指的就是这三个 Annotation:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
1.@SpringBootConfiguration
- 可以看到这个注解只是@Configuration注解的派生注解
- 跟@Configuration注解的功能一致,标注这个类是一个配置类
- 只不过@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解
- @Configuration 对我们来说并不陌生,它就是 JavaConfig 形式的 Spring IoC 容器的配置类使用的那个 @Configuration
- 既然 SpringBoot 应用骨子里就是一个 Spring 应用,那么自然也需要加载某个 IoC 容器的配置
- 而 SpringBoot 社区推荐使用基于 JavaConfig 的配置形式,所以,很明显,这里的启动类标注了 @SpringBootConfiguration之后,本身其实也是一个 IoC 容器的配置类!
2.@EnableAutoConfiguration
作用:开启自动配置
- 借助于 Spring 框架原有的一个工具类:SpringFactoriesLoader 的支持
- @EnableAutoConfiguration 可以“智能”地自动配置
- SpringFactoriesLoader 属于 Spring 框架私有的一种扩展方案(类似于 Java 的 SPI 方案 java.util.ServiceLoader)
- 其主要功能就是从指定的配置文件 META-INF/spring.factories 加载配置
- spring.factories 是一个典型的 java properties 文件
- 配置的格式为 Key=Value 形式
- 只不过 Key 和 Value 都是 Java 类型的完整类名(Fully qualified name)
回到@EnableAutoConfiguration源码中
除去元注解就剩下@AutoConfigurationPackage和@Import
@AutoConfigurationPackage
- 是将 添加该注解的类所在的包 作为 自动配置package 进行管理
- 也就是当SpringBoot应用启动时默认会将启动类所在的package作为自动配置的package
- 从源码上看,本质是@Import({Registrar.class})
- @Import({Registrar.class})底层原理是通过反射将主配置类所在包及子包扫描到spring容器中
@Import({AutoConfigurationImportSelector.class})
- 借助AutoConfigurationImportSelector将所有符合自动配置条件的 bean 定义加载到 IoC 容器
所以@EnableAutoConfiguration 其实就变成了:
- 从 classpath 中搜寻所有 META-INF/spring.factories 配置文件
- 并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration 对应的配置项
- 通过反射(Java Reflection)实例化为对应的标注了 @Configuration 的 JavaConfig 形式的 IoC 容器配置类,然后汇总为一个并加载到 IoC 容器。
3.@ComponentScan
Spring注解,自动扫描并加载符合条件的组件或 bean 定义,最终将这些 bean 定义加载到容器中