@SpringBootApplication
使用IDEA快速构建一个SpringBoot项目,使用的SpringBoot版本为2.1.6.RELEASE
@SpringBootApplication是一个复合的注解,但实际上对于SpringBoot应用来说,重要的只有三个
@Configuration
@EnableAutoConfiguration
@ComponentScan
所以如果我们使用如下的SpringBoot启动类,整个SpringBoot应用依然可以与之前的启动类功能对等。
@Configuration
这里的@Configuration,它就是Spring IoC容器的配置类使用的那个@Configuration,既然SpringBoot应用骨子里就是一个Spring引用,自然也需要加载某个IoC容器的配置,这里启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类!很多SpringBoot的代码示例都喜欢在启动类上直接标注@Configuration或者@SpringBootApplication,对于初接触SpringBoot的开发者来说,其实这种做法不便于理解,如果我们将上面的SpringBoot启动类拆分为两个独立的Java类,整个形式就明朗了:
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoConfiguration.class, args);
}
}
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class DemoConfiguration(){
@Bean
public Controller controller(){
return new Controller();
}
}
所以,启动类DemoApplication就是一个标准的main函数启动类,而@Configuration标注的DemoConfiguration定义其实也是一个普通的JavaConfig形式的IoC容器配置类,全是Spring框架的概念。
@EnableAutoConfiguration
@EnableAutoConfiguration类似于Spring框架中的提供的各种以@Enable的注解,比如@EnableScheduling、@EnableMBeanExport等,都是借助@Import的支持,收集和注册特定场景相关的bean定义:
@EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器。
@EnableMBeanExport是通过@Import将JMX相关的bean定义加载到IoC容器。
而@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。
最关键的是@Import(AutoConfigurationImportSelector.class)
,借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。那么,AutoConfigurationImportSelector又是如何加载的呢?
查看AutoConfigurationImportSelector类的源码,它依赖于SpringFactoriesLoader的loadFactoryNames方法,来获取一组自动配置类名。
自动配置的幕后英雄:SpringFactoriesLoader
它的主要功能就是从指定的配置文件META-INF/spring.factories加载配置,配置的格式为Key = Value形式,只不过key和value都是Java类型的完整类名,比如:
example.MyServer=example.MyServerImpl1,example.MyServerImpl2
然后框架就可以根据某个类型作为Key来查询对应的类型名称列表了,对于AutoConfigurationImportSelector来说,即根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应一组@Configuration类:
以上是从SpringBoot的autoconfigure依赖包中的META-INF/spring.factories配置文件中截取的一部分内容,可以很好的说明问题。
所以,@EnableAutoConfiguration自动配置就是从classpath中搜索所有META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置项通过反射实例化对应的@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。
@ComponentScan
@ComponentScan对应XML配置形式中的<context:component-scan>
元素,用于配合@Component和@Repository等注解,将标注了这些注解的bean定义类批量采集到Spring的IoC容器中。
我们可以通过basePackages等属性来细粒度地定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。
参考资料《SpringBoot揭秘 快速构建微服务体系》