0.o?让我看看怎么个事儿之SpringBoot自动配置
学习 SpringBoot 自动配置之前我们需要一些前置知识点:
学会@ConfigurationProperties月薪过三千
@Conditional+@Configuration有没有搞头?
首先我们提出2个问题:
SpringBoot 是干什么的?
是用来简化 Spring 原生的复杂的 xml 配置的进阶框架。
自动配置是什么?
我们用另外一个问题回答这个问题。
我们在 SpringBoot 开发中,就写了几个配置,怎么连接上的数据库?
spring:
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.0.0.1:3306/test?useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: root
在新手村时期,我们照着教程生搬硬抄的时候可能也想过这个问题,今天就来简单探究一下。
再次强调:
看明白本篇内容需要前置知识点,尤其是 @Import 注解。
这一切都要从 @SpringBootApplication 注解讲起。
@SpringBootApplication
@SpringBootApplication 注解是一个复合注解,它由如下三个注解组成。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration // 第一个
@EnableAutoConfiguration // 第二个
@ComponentScan(excludeFilters = { // 第三个
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
@SpringBootApplication
├── @ComponentScan
├── @SpringBootConfiguration
│ └── @Configuration
└── @EnableAutoConfiguration
├── @Import(AutoConfigurationImportSelector.class)
└── @AutoConfigurationPackage
└── @Import(AutoConfigurationPackages.Registrar.class)
@SpringBootConfiguration
@ComponentScan
@EnableAutoConfiguration
从注解的中文意思中也可以看出来,第三个 @EnableAutoConfiguration 是与我们自动配置紧密相关的。
我们先快速搞定前2个。
@SpringBootConfiguration
这个最简单,把头套摘下来,他就是一个普普通通的 @Configuration 注解包装而成而已,表示当前类是一个配置类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 本体在这
public @interface SpringBootConfiguration {
}
@ComponentScan
可以指定basePackageClasses或basePackages(或其别名value)来定义要扫描的特定包。如果没有定义特定包,扫描将从声明此注解的类的包开始。
顾名思义就是扫描Component。
扫描哪里?
可以通过该注解的属性指定Spring应该扫描的包。如果没有指定包,则默认扫描声明 @ComponentScan 的类所在的包及其子包。
哪些Component?
使用 @Component, @Service, @Repository, @Controller 等注解的类。
扫描了做什么用?
将扫描到的组件注册为Spring的Bean,加入到ioC容器进行统一管理。
@EnableAutoConfiguration
这是自动配置的核心注解!
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}
我们能看到,其中有2个注解:
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
@AutoConfigurationPackage
我们再点进去看一下,发现它又是一个 @Import 。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
@Import(AutoConfigurationPackages.Registrar.class) 中的 Regisgrar 类如下:
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
如果你有去好好看 @Import 注解的那篇文章,就会知道这是 ImportBeanDefinitionRegistrar 接口实现的方式。
这种方式提供一种手动方式灵活注册 bean。
在这里,我们根据两个提示就可以知道其功能:
• @AutoConfigurationPackage 是自动配置包的意思
• register(registry, new PackageImport(metadata).getPackageName()); 根据包名注册 bean
总结一下就是:
根据通过注解提供的元数据,动态地向 Spring 容器中注册特定包中的类作为 beans。
@Import(AutoConfigurationImportSelector.class)
如果你有去好好看 @Import 注解的那篇文章,就会知道这是 ImportSelector接口实现的方式。
这种方式只需实现 selectImports 方法,并以数组的形式返回要导入的类名,即可实现批量注册组件。
AutoConfigurationImportSelector 类中通过自己的源码实现了如下一个功能:
把 spring-boot-autoconfigure 依赖中 META-INF/spring.factories 文件中需要自动配置的类名读取到数组中。
它长这个样子:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
...
那它到底怎么读取的?
这里我们不讨论具体实现,有兴趣且有实力的可以扒源码自己看一下。
当然这些类不会全部都用到,经过筛选,去除重复、去除相应功能模块未开启的配置类、去除人为exclude掉的,将剩余的最终配置类全类名String数组返回。
最后我们再来回收一下开始的那个问题。
我们在 SpringBoot 开发中,就写了几个配置,怎么连接上的数据库?
我们简单捋一下:
SpringBoot 启动。
@SpringBootApplication 注解生效。
@EnableAutoConfiguration 注解生效。
@Import(AutoConfigurationImportSelector.class) 注解生效。
读取到了org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration。
注册一个数据源bean。
读取到 xml 的数据源配置。
大功告成!
往期推荐:
● 学会@ConfigurationProperties月薪过三千
0.o?让我看看怎么个事儿之SpringBoot自动配置的更多相关文章
- springboot2.0.3源码篇 - 自动配置的实现,发现也不是那么复杂
前言 开心一刻 女儿: “妈妈,你这么漂亮,当年怎么嫁给了爸爸呢?” 妈妈: “当年你爸不是穷嘛!‘ 女儿: “穷你还嫁给他!” 妈妈: “那时候刚刚毕业参加工作,领导对我说,他是我的扶贫对象,我年轻 ...
- 【转】Sqlite 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该...
开发环境: vs2010+.net framework 4.0+ System.Data.SQLite.DLL (2.0)今天在做Sqlite数据库测试,一运行程序在一处方法调用时报出了一个异常 混合 ...
- SQLite.dll混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
其他信息: V5.7.4.4 Can't find the System.Data.SQLite.dll more info : 混合模式程序集是针对"v2.0.50727"版的运 ...
- Spring Boot自动配置源码解析(基于Spring Boot 2.0.2.RELEASE)
在Spring Boot官方介绍中,首一段话是这样的(如下图).我们可以大概了解到其所表达的含义:我们可以利用Spring Boot写很少的配置来创建一个非常方便的基于Spring整合第三方类库的单体 ...
- C#连接Sqlite 出现:混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。的解决方案
C#连接Sqlite 出现: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集.的解决方案 C#连接sqlite数据库代码 ...
- c# .netframwork 4.0 调用 2.0时报错 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
“System.IO.FileLoadException”类型的未经处理的异常在 XXX.dll 中发生 其他信息: 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的 ...
- 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。
在调用部分三方库时,由于三方库是基于.NET2.0的.所以在4.0的程序中无法加载.解决方案如下: 在配置文件中添加以下配置 <?xml version="1.0"?> ...
- 【原生态跨平台:ASP.NET Core 1.0(非Mono)在 Ubuntu 14.04 服务器上一对一的配置实现-篇幅1】
鸡冻人心的2016,微软高产年. build 2016后 各种干货层出不穷. 1 Win10 集成了bash ,实现了纳德拉的成诺,Microsoft Love Linux!!! 2 跨平台 ,收 ...
- Webstorm10.0.3破解程序及汉化包下载、Webstorm配置入门指南
核心提示: WebStorm 是jetbrains公司旗下一款JavaScript 开发工具.被广大中国JS开发者誉为“Web前端开发神器”.“最强大的HTML5编辑器”.“最智能的JavaSscri ...
- OpenCV3.0.0+win10 64位+vs2015环境的下载,安装,配置
操作系统:WIN10 pro 64 软件版本:VS2015+OpenCV3.0.0 1. 下载安装 http://opencv.org/ https://www.visualstudio.com/ ...
随机推荐
- 关于如何来测一款app的思考
最近工作当中需要整体测一遍app,需要全方面思考并且尽可能覆盖所有待测点,因为整理总结了这篇关于app测试的总体大纲 一.功能测试 1.1界面测试 1.1.1导航测试 ---是否易于导航.导航是否直观 ...
- 在 Windows 系统上运行 VIC 水文模型
目录 配置 WSL2 和 Ubuntu 系统 启用 WSL2 安装 Linux 发行版 配置 Ubuntu 安装 VIC 并测试 Stehekin 数据集 VIC 模型安装 samples 测试 VI ...
- 给 Web 前端工程师看的用 Rust 开发 wasm 组件实战
什么是wasm组件? wasm 全称 WebAssembly,是通过虚拟机的方式,可以在服务端.客户端如浏览器等环境执行的二进制程序.他有速度快.效率高.可移植的特点. 对我们 Web 前端工程最大的 ...
- Netty源码学习8——从ThreadLocal到FastThreadLocal(如何让FastThreadLocal内存泄漏doge)
系列文章目录和关于我 一丶引入 在前面的netty源码学习中经常看到FastThreadLocal的身影,这一篇我们将从ThreadLocal说起,来学习FastThreadLocal的设计(< ...
- [ABC265G] 012 Inversion
Problem Statement You are given a sequence $A=(A_1,\ldots,A_N)$ of length $N$. Each element is $0$, ...
- uniapp的下载
简介 - HBuilderX 文档 (dcloud.net.cn) 下载Hbuiler 直接打开HbuilderX.exe就可以直接使用 可以通过他来创建模板 目录
- Tensorflow2.0使用Resnet18进行数据训练
在今年的3月7号,谷歌在 Tensorflow Developer Summit 2019 大会上发布 TensorFlow 2.0 Alpha 版,随后又发布了Beta版本. Resnet18结构 ...
- Linux磁盘专题-常用分区命令
划分分区 fdisk 专门用于划分MBR类型的分区.(mbr分区类型在linx中也叫msdos) 注意:fdisk在centos7上已经可以用来划分gpt类型的分区. 详细不说了,N年之前学习过 gd ...
- 万界星空科技MES系统中的生产调度流程
MES系统生产调度的目标是达到作业有序.协调.可控和高效的运行效果,作业计划的快速生成以及面向生产扰动事件的快速响应处理是生产调度系统的核心和关键. 为了顺利生成作业计划,需要为调度系统提供完整的 ...
- 【scikit-learn基础】--『监督学习』之 决策树回归
决策树算法是一种既可以用于分类,也可以用于回归的算法. 决策树回归是通过对输入特征的不断划分来建立一棵决策树,每一步划分都基于当前数据集的最优划分特征.它的目标是最小化总体误差或最大化预测精度,其构建 ...