[SpringBoot] 自动装配原理分析
什么是自动装配
我们在使用SpringBoot的时候,SpringBoot会自动帮我们进行如下配置:
- 自动配置好Tomcat
- 自动配置好SpringMVC
- 自动配置好Web常见功能,如字符编码问题
- 默认的包结构
- 各种配置拥有默认值
- 按需加载所有自动配置项等等
自动装配原理分析
@SpringBootApplication
首先找到 SpringBoot 的主启动类
,在这个主启动类上存在有一个 @SpringBootApplication
的注解,SpringBoot 通过这个注解来说明这个类是主启动类,然后通过执行类中的main方法来启动 SpringBoot 项目
在main方法里面会执行一个run方法
,它会使用一个默认的配置来启动SpringApplication程序
然后看一下注解@SpringBootApplication究竟做了什么,它主要有如下两个重要注解:
@SpringBootConfiguration
@EnableAutoConfiguration
@SpringBootConfiguration
在@SpringBootConfiguration中,有这样一个注解**@Configuration**
点开 @Configuration 注解,我们发现,它实际上就是一个 @Component 注解,代表它是 SpringBoot 的一个组件,代表它是一个配置类
。
因此, @Configuration 注解仅代表其是一个配置类,类似的有:
@EnableAutoConfiguration
点开 @EnableAutoConfiguration 注解,我们发现除了元注解外,它主要有两个注解:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPackage
先来看 @AutoConfigurationPackage 注解,点开它,我们发现主要的注解是@Import(AutoConfigurationPackages.Registrar.class)
事实上,@Import
就是给容器中导入组件,@Import(AutoConfigurationPackages.Registrar.class)
就是给容器中导入Registrar组件
@Import(AutoConfigurationPackages.Registrar.class)
通过import注解导入了一个AutoConfigurationPackages下的一个静态内部类Registrar
,它的作用是给容器中批量注册组件
在Registrar类中,重写了方法registerBeanDefinitions,大概就是说注册定义的Bean,他要扫描的包是我们的主启动类,这时候就大概知道SpringBoot 就是通过这个注解来扫描主启动类下的包和子包下的所有组件
并加载到 Spring 容器。
@Import(AutoConfigurationImportSelector.class)
点进这个注解,我们发现他重写了selectImports
方法
而在selectImports
方法中,它又调用了getAutoConfigurationEntry
方法
当走完getCandidateConfigurations
时,它会加载很多configurations,这些都是自动配置类的全限定名
。
让我们来梳理一下现在已经知道的信息:SpringBoot 通过 @Import(AutoConfigurationImportSelector.class) 这个注解加载了我们 Spring 容器需要的所有配置类,可以知道这些配置类是通过getCandidateConfigurations()方法加载的,继续点进getCandidateConfigurations()方法
下面通过一个SpringFactoriesLoader调用了一个loadFactoryNames方法,点进SpringFactoriesLoader我们发现有一个工厂资源地址
因此在getCandidateConfigurations()方法中,它通过SpringFactoriesLoader.loadFactoryNames方法
扫描到META-INF/spring.factories
的jar包,并且将需要的自动配置包加载到 Spring 容器中
找到这个工厂资源地址:
发现这里面全部是全限定名
,所以就是在这里找到了自动配置类并且加载到了 Spring 容器中,完成自动配置类的加载。