目标:
了解 SpringBoot 的自动装配原理
学习步骤:
1、了解 父依赖管理特性 2、自动配置包 spring-boot-autoconfigure 3、自动配置原理
一、SpringBoot 父依赖管理特性
新建完项目,为什么我们只导入了这个包 就可以运行web项目了呢 ? 连依赖版本号都不用 ?
现实肯定不是这样子的,我们点进去 spring-boot-starter-web 看看
可以看到一个 spring-boot-dependencies 依赖,进去看看
往下拉可以看到一大堆版本信息
同样的,我们在 pom.xml 文件的开头也可以进入依赖管理文件
如果进不去,就降低版本
看了 spring-boot-dependencies 之后发现:核心依赖在父工程中!所以我们才不需要声明版本信息
我们在写或者引入一些 SpringBoot 依赖的时候,不需要指定版本,就因为有这些版本仓库
此时就有一个问题了 我们先看看这个情况
很大一部分公司MySQL用的是5版本的咋整?
肯定不能在这个文件进行修改呀,得在pom.xml文件中进行版本指定(重新覆盖)
比如还是想用 MySQL5版本
上面指定MySQL的版本后 , 下面引入同样无需写版本号
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
此时查看依赖项目版本信息
或者,还可以利用如下写法 指定MySQL的版本号信息,直接写版本号,但是这样子不容易做项目全局控制,一般公司的项目都有标明用什么技术的什么版本,所以我们一般都是在最上面的<properties> 属性中声明项目所需版本信息
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
二、自动配置包 spring-boot-autoconfigure
我们可以通过这个WEB启动器来挖掘 SpringBoot的自动配置包在哪里
进入该文件,可以看到还有一个spring-boot-starter 启动器
进入这个启动器,又可以看到一个spring-boot-autoconfigure 包 翻译过来就是自动配置类
SpingBoot 所有的自动配置功能都在 spring-boot-autoconfigure 包中,项目中有很多 starter 启动器,SpringBoot 会按需加载所有的自动配置项,只有引入了这个 starter 启动器,该场景下的自动配置才会开启
三、自动配置原理
3-1、引导加载自动配置类
还是从 Main 方法着手
查看 核心注解 @SpringBootApplication 注解
发现它其实就是下面 三个注解的整合
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
核心:换句话说就是将 @SpringBootApplication 注解替换成 这三个注解,程序照样正常运行
3-2、@SpringBootConfiguration 注解
进去看看
也就是说 这个注解 存在的意义 就是让我们的 主类 变成配置类 (此时主类就变成核心配置类)
3-3、@EnableAutoConfiguration 注解 (重点:开启自动配置功能)
点进去一看,发现是两个注解的合成
3-3-1、先看看 @AutoConfigurationPackage 注解
@AutoConfigurationPackage 注解的 这个 @Import 只是给容器中导入一个AutoConfigurationPackage.Registrar 组件
在容器中 导入一个注册类 Registrar , 进去看看
此时它利用 Registrar 给容器中导入一些组件(批量导入)
new PackageImports(metadata).getPackageNames() 就是在获取 Main类 的所在的包名 com.csnz , 转换为数组
所以 @AutoConfigurationPackage 注解 的作用就是 将Main主类包下的所有组件进行导入(即 com.csnz 包下)
3-3-2、再看 @Import 注解
发现 他是导入一个 AutoConfigurationImportSelector 包 ,这个包的作用也是 批量导入
进入此类中,往下拉可以看到一个方法
此方法 决定了我们需要导入的bean,它会封装成一个数组返回
进入这个 获取自动配置入口 的方法看看
此方法还有一个需要注意到的点,就是 获取候选配置方法
进去瞧瞧
看看 Spring工厂加载机制的 loadFactoryNames 方法
查看资源,发现他是从 META-INF/spring.factories 位置加载文件的,默认扫描我们当前系统里面所有 META-INF/spring.factories 位置的文件,因为有众多包拥有此文件,所以我们只需关注一个包即可,那就是自动配置包 spring-boot-autoconfigure-2.3.7.RELEASE.jar
那这个自动配置包 在哪里呢 ?
进入文件可以看到 Auto Configure 下有大量的自动配置类
文件里面写死了 SpringBoot 一启动就要给容器中加载的所有配置类
3-3-3、是否一启动就导入全部自动配置项呢?
肯定不是的,SpringBoot 会按需开启自动配置项
虽然我们 127 个场景的所有自动配置启动的时候默认全部加载,但是你打开具体文件,他里面是按照条件装配规则来决定是否加载的(@Conditional 注解),所以最终是会按需进行配置的
3-4、 @ComponentScan 注解
其实就是用于指定 spring 在初始化容器时要扫描的包,这在学习Spring初期注解就涉及到了
自动配置总结:
1. SpringBoot 先加载所有的自动配置类 xxxAutoConfiguration (比如批处理)
2. 每个自动配置类 会根据里面内部的条件 决定是否注入Bean,每个文件中都默认绑定了配置文件指定的值,从xxxProperties类中拿,而xxxProperties类又和配置文件进行了绑定
3. 生效的配置类就会给容器中装配很多组件 4. 只要容器中有这些组件,相当于这些功能就具有了 5.实现定制化配置
- 5-1. 第一种方式:用户自己 写方法 @Bean 替换底层的组件
- 5-2. 第二种方式:用户查看此组件是获取配置文件的什么值就去修改,根据组件文件中绑定的前缀信息去application.properties文件中修改即可
- 5-3. 流程:xxxAutoConfiguration ==> 对应的组件 ? xxxProperties类中拿值 ==> 在 application.properties中修改
|