大聪明教你学Java | 深入浅出聊 SpringBoot 中的 starter 机制

前言

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。
🍊支持作者: 点赞👍、关注💖、留言💌~

我们都知道,Spring 的功能非常强大,但也存在一些弊端。例如我们需要手动去配置大量的参数,需要我们管理大量的 jar 包等等。后来,官方为了简化配置,同时可以让开发者们能更好的专注于业务的开发,Spring 官方引入了 SpringBoot 的概念。提到 SpringBoot 各位小伙伴肯定是不陌生了,我们几乎每天都在和它打交道,就是不知道各位小伙伴在使用 SpringBoot 的时候有没有注意过 pom.xml 中的 starter 依赖呢~ 今天大聪明就和大家深入浅出聊 SpringBoot 中的 starter 机制😊

SpringBoot 中的 starter 机制

什么是 starter

SpringBoot 在配置上相比 Spring 要简单许多, 其核心在于 spring-boot-starter,在使用 SpringBoot 来搭建一个项目时,只需要引入官方提供的 starter 后就可以直接使用,免去了各种繁琐的配置流程。简单来讲就是,starter 帮助开发者们引入了一些相关依赖和一些初始化的配置,从而可以让开发者们更专注于开发。Spring 官方提供了很多 starter,第三方也可以定义 starter。为了加以区分,starter从名称上进行了如下规范:

  • Spring 官方提供的 starter 名称为 spring-boot-starter-xxx,例如 spring-boot-starter-web
  • 第三方提供的 starter 名称为 xxx-xxx-boot-starter,例如由苞米豆提供的 mybatis-plus-boot-starter

说到这,各位小伙伴可能有疑问了,SpringBoot 为什么可以帮我们简化项目的搭建的工作呢?它是如何做到这点的呢?🤔

其实这就要归功于它提供的两大功能了,起步依赖和自动配置。

起步依赖

起步依赖,其实就是将具备某种功能的相关依赖打包到一起,这样可以简化依赖导入的过程(我们可以将其理解为依赖整合)。例如,我们在导入 spring-boot-starter-web 时,和 web 开发相关的依赖都一起导入到项目中了。我们点开 spring-boot-starter-web 依赖后就可以发现,它下面还包含着众多所需要的基础依赖 👇

在这里插入图片描述

自动配置

自动配置,顾名思义就是无须手动配置 xml 文件,当我们引入相关依赖后就可以自动配置并管理 bean,极大的简化了开发过程。SpringBoot 完成自动配置共分为五个关键的步骤:

  1. 基于配置文件的 Bean 配置
  2. 自动配置条件依赖
  3. Bean 参数获取
  4. Bean 的发现
  5. Bean 的加载

接下来我们以 mybatis-plus-boot-starter 为例子,具体说一下这五个流程👇

🍊 ① 基于配置文件的 Bean 配置 🍊
当我们引入了 mybatis-plus-boot-starter 后,我们可以从依赖中找到对应的 jar 包,我们打开 jar 包可以找到一个关键的 MybatisPlusAutoConfiguration 配置文件,如下图所示 👇

在这里插入图片描述

在这里插入图片描述

熟悉 @Configuration 和 @Bean 这两个注解的小伙伴们或许已经明白了。这两个注解一起使用就可以创建一个可以替代 xml 配置文件的配置类。添加了 @Configuration 注解的类可以看作是能让 Spring IOC 容器管理的 Bean 实例的工厂。@Bean 注解可以告诉 Spring,带有 @Bean 的注解方法将返回一个对象,并且该对象需要被注册到 Spring 容器中。所以上面的 MybatisPlusAutoConfiguration 配置类,自动帮我们生成了 sqlSessionFactory 等重要的实例并将他们交给 Spring 容器管理,从而完成 Bean 的自动注册。

🍊 ② 自动配置条件依赖 🍊

在这里插入图片描述
通过 MybatisPlusAutoConfiguration 配置文件中添加的 @ConditionalOnClass 和 @ConditionalOnSingleCandidate 注解可以发现,需要完成自动配置是有依赖条件的,即需要在当前类的路径上存在 SqlSessionFactory.class 和 SqlSessionFactoryBean.class,同时需要存在已完成自动注册的 DataSource Bean,才可以完成自动配置。

这里我们顺便再说几个特殊的注解 👇

  • @ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
  • @ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
  • @ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
  • @ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
  • @ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
  • @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
  • @ConditionalOnExpression:基于SpEL表达式的条件判断。
  • @ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
  • @ConditionalOnResource:当类路径下有指定的资源时触发实例化。
  • @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
  • @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。

🍊 ③ Bean 参数获取 🍊

要完成 mybatis-plus 的自动配置,需要在配置文件中提供相关的配置参数,我们可以看到 MybatisPlusAutoConfiguration 配置文件中还写上了 @EnableConfigurationProperties 注解 👇

在这里插入图片描述

我们继续追踪源码,打开 MybatisPlusProperties.class 文件后可以发现,这个类上写着 @ConfigurationProperties 注解,这个注解的作用就是把 .yml 文件或者 .properties 配置文件中的配置参数信息封装到 @ConfigurationProperties 注解标注的 Bean (即 MybatisPlusProperties )的相应属性上,而 @EnableConfigurationProperties 注解的作用则是使 @ConfigurationProperties 注解生效。

在这里插入图片描述

🍊 ④ Bean 的发现 🍊
SpringBoot 默认扫描启动类所在的包下的主类与子类的所有组件,但并没有包括依赖包中的类,那么依赖包中的 Bean 又是如何被发现和加载的呢?下面我们就需要从 SpringBoot 项目的启动类开始跟踪了,在启动类上我们一般会加上 @SpringBootApplication 注解,源码如下 👇

在这里插入图片描述
我们都知道 @SpringBootApplication 主要是由三个注解构成:

  1. @SpringBootConfiguration:作用就相当于 @Configuration 注解,被添加了注解的类将成为一个Bean 配置类
  2. @ComponentScan:作用就是自动扫描并加载符合条件的组件,最终将这些 Bean 加载到 Spring 容器中
  3. @EnableAutoConfiguration :借助 @Import 注解的支持,收集和注册依赖包中相关的 Bean

接下来我们再看看 @EnableAutoConfiguration 注解 👇

在这里插入图片描述
我们可以发现 @EnableAutoConfiguration 注解又引入了 @Import 注解。导入了 AutoConfigurationImportSelector.class,AutoConfigurationImportSelector.class 源码如下 👇

在这里插入图片描述
我们在 AutoConfigurationImportSelector.class 源码中可以发现,getCandidateConfigurations 方法中调用了 SpringFactoriesLoader 类的 loadFactoryNames 方法,我们继续跟踪源码👇

在这里插入图片描述
关键的一行代码出现了,getResources 方法中调用了一个名为 FACTORIES_RESOURCE_LOCATION 的静态变量,这个静态变量对应的值就是 META-INF/spring.factories

在这里插入图片描述
看到这里,相信各位小伙伴应该已经清楚了,SpringFactoriesLoader 的 loadFactoryNames 静态方法可以从所有的 jar 包中读取 META-INF/spring.factories 文件,我们回过头再看一下 mybatis-plus-boot-starter 依赖,可以发现在 mybatis-plus-boot-starter 依赖中的 spring.factories 配置文件里有这样两行配置。也正是通过这个配置,可以让 SpringBoot 加载到 MybatisPlusAutoConfiguration 配置类了。 👇

在这里插入图片描述
🍊 ⑤ Bean 的加载 🍊

通过第四步的讲解,相信各位小伙伴也理解了 Bean 的加载流程,SpringBoot 使用 @Import 注解实现了自动配置,从 META-INF/spring.factories 文件中读取到的主配置文件的全类名,这样 SpringBoot 就可以加载到主配置文件中涉及到的 Bean 并完成实例的创建工作。

starter 的关键构成要素

通过上面的讲解,我们可以总结出构成 starter 的几个关键要素 👇

在这里插入图片描述

俗话说,要把大象装冰箱一共分为三步,那么如果自己需要开发一个 starter 一共分为几步呢?没错~~ 也是三步,最后我们来总结一下开发 starter 的三个步骤:

🍇 创建一个名为 xxx-xxx-boot-starter的空项目,并在pom.xml文件里引入自己所需的依赖。
🍇 开发自己所需的业务逻辑,业务开发完成后创建名为 xxxAutoConfiguration(或 xxxConfiguration) 的主配置类,在该类下定义一些所需的 Bean 实例
🍇 创建 spring.factories 配置文件,并在配置文件中引入主配置类org.springframework.boot.autoconfigure.EnableAutoCoinfiguration=xxx.xxx.xxx.xxxAutoConfiguration(或 xxxConfiguration)

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●’◡’●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

你在被打击时,记起你的珍贵,抵抗恶意;
你在迷茫时,坚信你的珍贵,抛开蜚语;
爱你所爱 行你所行 听从你心 无问东西

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/2250.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网络安全横向移动指南

在网络安全方面,了解威胁参与者的工具、技术和思维过程非常重要。 一旦对手获得对网络的初始访问权限,横向移动允许他们通过破坏目标组织网络中的其他主机来扩展访问权限并保持持久性。 威胁行为者可以收集有关公司用户活动和凭据、重要数据位置的信息…

Spark - 继承 FileOutputFormat 实现向 HDFS 地址追加文件

目录 一.引言 二.源码浅析 1.RDD.saveAsTextFile 2.TextOutputFormat 3.FileOutputFormat 三.源码修改 1.修改文件生成逻辑 - getRecordWriter 2.允许目录存在 - checkoutputSpecs 3.全部代码 - TextOutputFormatV2 四.追加存储代码实战 五.总结 一.引言 Output d…

关于STM32用DMA传输UART空闲中断中接收的数据时无法接收数据问题以及解决办法

一、stm32 cube ide 配置 1、DMA串口接收数据的ide配置如下图所示 串口1相关的设置及printf函数的使用,这里没放,建议先实现串口打印功能 2、相关的知识点 普通模式和循环模式的区别在于,普通模式下,DMA只会接收一次数据&#x…

微前端(无界)

前言:微前端已经是一个非常成熟的领域了,但开发者不管采用哪个现有方案,在适配成本、样式隔离、运行性能、页面白屏、子应用通信、子应用保活、多应用激活、vite 框架支持、应用共享等用户核心诉求都或存在问题,或无法提供支持。本…

DS18B20温度传感器简介和1-Wire驱动程序

目录DS18B20简介DS18B20的两种供电方式64位ROM温度传感器1-Wire Bus简介DS18B20通信时序初始化ROM相关命令(后续包含任何数据交换的操作)功能相关命令(后续包含任何数据交换的操作)单个DS18B20读取温度值驱动多个DS18B20读取温度值驱动DS18B20简介 DS18B20数字温度计提供9位到…

学习系统编程No.7【进程替换】

引言: 北京时间:2023/3/21/7:17,这篇博客本来昨天晚上就能开始写的,但是由于笔试强训的原因,导致时间用在了做题上,通过快2个小时的垂死挣扎,我充分意识到了自己做题能力的缺陷和运用新知识的缺…

致远OA敏感信息泄露漏洞合集(含批量检测POC)

文章目录前言敏感信息泄露A6 status.jsp 信息泄露漏洞漏洞描述漏洞影响网络测绘漏洞复现POC 批量检测getSessionList.jsp Session泄漏漏洞漏洞描述网络测绘批量检测POC致远OA 帆软组件 ReportServer 目录遍历漏洞漏洞描述漏洞影响网络测绘POC(批量检测)A6 createMysql.jsp 数据…

Java stream性能比较

环境 Ubuntu 22.04IntelliJ IDEA 2022.1.3JDK 17CPU:8核 ➜ ~ cat /proc/cpuinfo | egrep -ie physical id|cpu cores physical id : 0 cpu cores : 1 physical id : 2 cpu cores : 1 physical id : 4 cpu cores : 1 physical id : 6 cpu cores : 1 physical id …

浏览器工作原理

一、JavaScript 的历史 JavaScript(简称JS)Web前端开发的脚本语言。 它诞生1995年,由网景公司的 Brendan Eich 开发。最初,JavaScript 被设计用于在网页上嵌入动态内容和交互式功能。 1996年,JavaScript 1.1 成为国…

C++虚函数与多态

C虚函数与多态虚函数抽象类纯虚函数虚析构函数多态虚函数的几个问题纯虚函数和ADT虚函数 virtual修饰的成员函数就是虚函数, 1.虚函数对类的内存影响:增加一个指针类型大小(32位和64位) 2.无论有多少个虚函数,只增加一…

【ansible】模块介绍超详解(下)

目录 六,软件包管理 1,yum_repository模块 (1)yum_repository模块常用选项 (2)yum_repository模块案例 2,mount模块 (1)mount模块选项 (2)mount模…

大数据简介

大数据概论和职业规划Linux服务器系统Hadoop概论HDFS分布式文件系统Hive数据仓库SparSQL指令Zepplin框架Sqoop框架Superset数据可视化大数据数仓实战-didi出行大数据概念大数据特点大数据应用场景大数据分析业务步骤大数据职业规划大数据学习路线。大数据概念数据:世…

基于YOLOv5的舰船检测与识别系统(Python+清新界面+数据集)

摘要:基于YOLOv5的舰船检测与识别系统用于识别包括渔船、游轮等多种海上船只类型,检测船舰目标并进行识别计数,以提供海洋船只的自动化监测和管理。本文详细介绍船舰类型识别系统,在介绍算法原理的同时,给出Python的实…

【系统开发】WebSocket + SpringBoot + Vue 搭建简易网页聊天室

文章目录一、数据库搭建二、后端搭建2.1 引入关键依赖2.2 WebSocket配置类2.3 配置跨域2.4 发送消息的控制类三、前端搭建3.1 自定义文件websocket.js3.2 main.js中全局引入websocket3.3 App.vue中声明websocket对象3.4 聊天室界面.vue3.5 最终效果一、数据库搭建 很简单的一个…

数据结构与算法——二叉树+带你实现表达式树(附源码)

📖作者介绍:22级树莓人(计算机专业),热爱编程<目前在c++阶段,因为最近参加新星计划算法赛道(白佬),所以加快了脚步,果然急迫感会增加动力>——…

ThreadLocal详解

一、什么是ThreadLocal 1、什么是ThreadLocal&为什么用ThreadLocal ThreadLocal,即线程本地变量,在类定义中的注释如此写This class provides thread-local variables。如果创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有…

C++基础算法④——排序算法(插入、桶附完整代码)

排序算法 1.插入排序 2.桶排序 1.插入排序 基本思想:将初始数据分为有序部分和无序部分;每一步将无序部分的第一个值插入到前面已经排好序的有序部分中,直到插完所有元素为止。步骤如下: 每次从无序部分中取出第一个值&#x…

图像分类卷积神经网络模型综述

图像分类卷积神经网络模型综述遇到问题 图像分类:核心任务是从给定的分类集合中给图像分配一个标签任务。 输入:图片 输出:类别。 数据集MNIST数据集 MNIST数据集是用来识别手写数字,由0~9共10类别组成。 从MNIST数据集的SD-1和…

在Clion开发工具上使用NDK编译可以在安卓上执行的程序

1. 前言 因为工作需要,我要将一份C语言代码编译成可执行文件传送到某安卓系统里执行。 众所周知,使用ndk编译代码有三种使用方式,分别是基于 Make 的 ndk-build、CMake以及独立工具链。以前进行ndk编程都是使用ndk-build进行的,新…

RocketMQ的基本概念、系统架构、单机安装与启动

RocketMQ的基本概念、系统架构、单机安装与启动 文章目录RocketMQ的基本概念、系统架构、单机安装与启动一、基本概念1、消息(Message)2、主题(Topic)3、标签(Tag)4、队列(Queue)5、…
最新文章