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/ ...
随机推荐
- 将强化学习引入NLP:原理、技术和代码实现
本文深入探讨了强化学习在自然语言处理(NLP)中的应用,涵盖了强化学习的基础概念.与NLP的结合方式.技术细节以及实际的应用案例.通过详细的解释和Python.PyTorch的实现代码,读者将了解如何 ...
- DFS深搜小谈
前几天有人跟我说,啊,说dfs一搜搜着搜着就把自己搜蒙了,说一写dfs就要dfs(int a,int b,int c),括号里面放一堆东西.啊今天我要澄清一下,dfs其实没有你想的那么复杂. dfs这 ...
- C#12中的Collection expressions(集合表达式语法糖)
C#12中引入了新的语法糖来创建常见的集合.并且可以使用..来解构集合,将其内联到另一个集合中. 支持的类型 数组类型,例如 int[]. System.Span<T> 和 System. ...
- 自学day7 数组
typora-copy-images-to: media 数组 一.概念 对象中可以通过键值对存储多个数据,且数据的类型是没有限制的,所以通常会存储一个商品的信息或一个人的信息: var obj = ...
- 基于 Echarts实现可视化数据大屏展示?
当涉及到使用Echarts实现可视化数据大屏展示时,以下是一份非常详细的介绍说明. 第一部分:介绍Echarts Echarts是一个由百度开源的基于JavaScript的可视化图表库.它支持多种图表 ...
- 基于uQRCode封装的Vue3二维码生成插件
标题:基于uQRCode封装的Vue3二维码生成插件 摘要:本文介绍了一种基于uQRCode封装的Vue3二维码生成插件,可以在Javascript运行环境下生成二维码并返回图片地址.该插件适用于所有 ...
- 明解Java第二章练习题答案
练习2-1 请对代码清单2-6的2处进行修改,将带有小数部分的实数值赋给x和y,查看结果如何? 答案:编译器会报错,因为小数的默认类型double是比int更大的类型.如果给double类型的变量赋值 ...
- DFT与ATE IP TEST
IP的DFT设计测试与ATE IP TEST是一个设计,测试活动吗? 不是. 这两个设计对于前端工农村很容易搞混,认为是同一个人负责,同一个活动.实际情不是. DFT主要空DSC控制器对IP进行扫描, ...
- springBoot——多环境开发
不常用的application.properties版的 常用的:application.yml版 #多环境开发,设置启用环境 spring: profiles: active: test --- # ...
- ubuntu 20.04系统上安装teleport开源堡垒机
ubuntu 20.04安装部署teleport堡垒机 简介:Teleport是一款简单易用的开源堡垒机系统,具有小巧.易用的特点,支持 RDP/SSH/SFTP/Telnet 协议的远程连接和审计管 ...