Springboot自动配置原理(详细易懂)

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());这个方法,

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4o0BG008-1598458218500)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200827000109183.png)]

总结:

Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值将这些值作为自动配置类导入到容中,自动配置类就生效,帮我们进行自动配置工作;

在这里插入图片描述

我们随便点一个WebMvcAutoConfiguration里面又@Configuration和@Bean对应的注解,所以说springboot自动配置了。
在这里插入图片描述


版权声明:本文为weixin_44359566原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。