springBoot自动装配原理

摘抄于https://www.cnblogs.com/shamo89/p/8184960.html,https://www.cnblogs.com/hellokuangshen/p/12450327.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@SpringBootApplication
@SpringBootConfiguration// 继承了Configuration,表示当前是配置类
@ComponentScan// 自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中
//@EnableAutoConfiguration也是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IOC容器
@EnableAutoConfiguration// 开启springboot的注解功能,springboot的四大神器之一,其借助@import的帮助
@AutoConfigurationPackage// 自动配置包注册
@Import(AutoConfigurationPackages.Registrar.class)// 导入当前主程序类的 *同级以及子级*的包组件
@Import(AutoConfigurationImportSelector.class)// 导入自动配置的组件

@SpringBootApplication主要做了以下四件事情:
1、推断应用的类型是普通的项目还是Web项目
2、查找并加载所有可用初始化器,设置到initializers属性中
3、找出所有的应用程序监听器,设置到listeners属性中
4、推断并设置main方法的定义类,找到运行的主类

@ComponentScan的功能其实就是自动扫描并加载符合条件的组件(比如@Component和@Repository等)或者bean定义,最终将这些bean定义加载到IoC容器中。我们可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。

注:所以SpringBoot的启动类最好是放在root package下,因为默认不指定basePackages。

1
2
3
4
5
6
7
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
//new PackageImport(metadata).getPackageName(),它其实返回了当前主程序类的 *同级以及子级*的包组件
}
}
1
2
3
4
5
6
AutoConfigurationImportSelector 继承了 DeferredImportSelector 继承了 ImportSelector

ImportSelector中声明了一个方法为:selectImports。
AutoConfigurationImportSelector实现了这个方法:selectImports
作用是:加载外部文件(spring-boot-autoconfiguration下的META-INF/spring.factories)
这个外部文件,有很多自动配置的类

img

img

img