Springboot自动配置原理
Spring Boot的启动类上有一个@SpringBootApplication注解,这个注解是Spring Boot项目必不可少的注解。那么自动配置原理一定和这个注解有着千丝万缕的联系!
//@SpringBootApplication 来标注一个主程序类 , 说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
public static void main(String[] args) {
//以为是启动了一个方法,没想到启动了一个服务
SpringApplication.run(SpringbootApplication.class, args);
}
}
我们来分析一下这些注解都干了什么
@SpringBootApplication
作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;
进入这个注解:可以看到上面还有很多其他注解!
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
// ......
}
@SpringBootConfiguration
作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;我们继续进去这个注解查看
// 点进去得到下面的 @Component
@Configuration
public @interface SpringBootConfiguration {}
@Component
public @interface Configuration {}
@Configuration
这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!
我们回到 SpringBootApplication 注解中继续看。
@EnableAutoConfiguration
@EnableAutoConfiguration :开启自动配置功能
以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉 SpringBoot开启自动配置功能;这样自动配置才能生效;
点进注解接续查看:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
@AutoConfigurationPackage : 自动配置包
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
@Import(AutoConfigurationPackages.Registrar.class)
Spring底层注解@import , 给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class这个类来指定
我们点进Registrar.class
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
注册metadata元数据的报名
debug发现,这个metadat是在springbootApplication下的,而且是作用在启动类里面
计算这个metadata包名(PackageImport(metadata).getPackageName()),得到的是主启动类的包名com.itwh
所以@AutoConfigurationPackage的作用是将主配置类(@SpringBootApplication标注的类)的所在包及下面所有的子包里面的所有组件扫描到Spring容器中。所以controller、service之类的包必须在和主启动类在同一包下。
我们再回到上一级@EnableAutoConfiguration开启自动配置这个注解里面的注解@Import
@Import
@Import(AutoConfigurationImportSelector.class)
给容器中导入组件
AutoConfigurationImportSelector.class就是导入组件的选择器
我们点进去这个类,里面有一个方法
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
里面有这么一个方法
getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
//上面方面里面又有一个方法
getCandidateConfigurations(annotationMetadata, attributes);//用于获取候选的配置文件
再点进去getCandidateConfigurations这个方法
主要有下面这个方法
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
有两个参数,第一个参数点进去,是返回这个EnableAutoConfiguration.class类,第二个参数是类加载器
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
得到EnableAutoConfiguration.class类和类加载器之后,也就是loadFactoryNames(EnableAutoConfiguration.class,ClassLoader);
点进去loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());这个方法,
总结:
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值将这些值作为自动配置类导入到容中,自动配置类就生效,帮我们进行自动配置工作;
我们随便点一个WebMvcAutoConfiguration里面又@Configuration和@Bean对应的注解,所以说springboot自动配置了。