重学SpringBoot3-SPI机制

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》
期待您的点赞👍收藏⭐评论✍

重学SpringBoot3-SPI机制

  • 什么是 SPI?
  • Spring Boot 中的 SPI 机制
    • spring.factories 文件
    • 自动配置的实现
    • 启动流程中的作用
  • SPI实际应用
    • 步骤 1: 新建模块
    • 步骤 2: 创建自动配置类
    • 步骤 3: 注册自动配置类
    • 步骤 4: 使用
    • 步骤 5: 测试
  • 最佳实践与注意事项
    • 1. 明确条件注解
    • 2. 避免类路径问题
    • 3. 使用 `@ConditionalOnMissingBean`
    • 4. 文档和示例
    • 5. 分离自动配置和业务逻辑
  • 总结

Spring Boot 的核心特性之一是其强大的自动配置功能,它极大地简化了 Spring 应用程序的配置。这种自动配置部分依赖于 Spring Boot 的服务提供者接口(SPI)机制,它允许开发者以模块化和可插拔的方式扩展和定制框架行为。接下来将详细探讨 Spring Boot 3 中的 SPI 机制,并通过示例展示如何实际使用它来实现。

什么是 SPI?

SPI(Service Provider Interface)即服务提供者接口,是一种服务发现机制,允许开发者和框架发现和加载可用的服务实现,而不需要在代码中硬编码具体的实现。这种机制使得软件系统能够更加灵活和可扩展。

在 Java 平台上,SPI 通常是通过 java.util.ServiceLoader 类实现的,但 Spring Boot 对这一概念进行了扩展,以支持其自动配置和模块化架构。

Spring Boot 中的 SPI 机制

Spring Boot 利用 spring.factories (注意:从 SpringBoot 2.7 起自动配置不推荐使用 /META-INF/spring.factories 文件,而是在/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports)文件,位于每个项目根目录的 META-INF/ 目录下,来实现其 SPI 机制。这个文件列出了与自动配置相关的接口及其实现类,Spring Boot 启动时会加载这些配置。

spring.factories 文件

这个文件使用键值对的格式列出了多种服务类型及其对应的实现类,常见的服务类型包括:

  • org.springframework.boot.autoconfigure.EnableAutoConfiguration:用于自动配置。
  • org.springframework.context.ApplicationListener:用于应用事件监听器。
  • org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider:用于模板引擎的可用性判断。

以下是 spring.factories 文件的一个典型例子:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.JpaAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

org.springframework.context.ApplicationListener=\
com.example.MyApplicationListener

Spring Boot 3 则要在 resources/META_INFO/spring/ 目录下新建 org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件,并填入需要自动配置的类的全路径:

com.example.JpaAutoConfiguration

自动配置的实现

在 Spring Boot 中,自动配置类使用 @ConditionalXxx 注解来控制配置类的加载条件。这允许 Spring Boot 根据当前应用的环境,如类路径上的类、环境变量、系统属性等,条件性地应用配置,例如,一个自动配置类可能只在 JPA 实体类存在时才加载:

@Configuration
@ConditionalOnClass(name = "javax.persistence.Entity")
public class JpaAutoConfiguration {
    // 配置 JPA 相关的 beans
}

启动流程中的作用

在 Spring Boot 的启动流程中,当 SpringApplication 类被调用时,它将初始化一个 SpringApplicationContext。在这个过程中,Spring Boot 通过 SpringFactoriesLoader 类来加载 spring.factoriesorg.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中定义的各种组件,包括自动配置类。然后,根据应用的实际环境(比如类路径上的库和定义的 Beans),以及自动配置类上的条件注解,决定是否激活这些自动配置类。

SPI实际应用

让我们通过一个自定义 stater 示例来展示如何创建和使用自定义的自动配置。

步骤 1: 新建模块

自定义的 starter 不需要启动类,需要删掉。

步骤 2: 创建自动配置类

创建一个自动配置类,这个类将提供一个服务,仅在某个特定的类如 SpecificClass 存在于启动类类路径上时才加载 MyService 类型的 bean。

package com.coderjia.spi.config;

import com.coderjia.spi.service.MyService;
import com.coderjia.spi.service.impl.MyServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author CoderJia
 * @create 2024/5/5 下午 03:29
 * @Description
 **/

@Configuration
@ConditionalOnClass(name = "com.coderjia.features.config.SpecificClass")
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public MyService MyService() {
        return new MyServiceImpl();
    }
}

MyService 类简单实现:

public class MyServiceImpl implements MyService {
    @Override
    public void sayHello() {
        System.out.println("hello");
    }
}

步骤 3: 注册自动配置类

接下来,SpringBoot 2.7 以下在模块的 META-INF/spring.factories 文件中注册这个自动配置类:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.coderjia.spi.config.MyAutoConfiguration

SpringBoot 2.7 及以上在 /META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中添加自动配置类:

com.coderjia.spi.config.MyAutoConfiguration

这样配置后,只要 SpecificClass 类存在于类路径上,Spring Boot 就会自动配置 MyService

步骤 4: 使用

在其他项目中,只需 pom 文件中引入我们自定义的 starter 依赖,并确保 SpecificClass 类在类路径上,Spring Boot 将自动应用这个配置。

        <dependency>
            <groupId>com.coderjia</groupId>
            <artifactId>spring-boot3-07-spi</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

步骤 5: 测试

首先,如果当前项目中启动类所在路径及其子路径不存在 SpecificClass 类,则从 IOC 容器中取不到 MyService

不存在SpecificClass类

当在当前项目中创建了 SpecificClass 类,则可以正常拿到 MyService bean:

存在SpecificClass类

最佳实践与注意事项

在利用 Spring Boot 的 SPI 机制开发自定义 starter 或自动配置时,有几个最佳实践和注意事项可以帮助确保项目的成功和维护性:

1. 明确条件注解

使用条件注解(如 @ConditionalOnClass@ConditionalOnBean)时,应尽量明确条件,确保你的自动配置仅在满足特定条件时才应用。这避免了配置冲突和非预期的行为,特别是在复杂的项目中。

2. 避免类路径问题

在设计自动配置时,注意类路径上可能出现的冲突。例如,如果自动配置依赖于某个库,确保这个库不会与项目中已有的库版本冲突。

3. 使用 @ConditionalOnMissingBean

在定义提供服务的 Bean 时,使用 @ConditionalOnMissingBean 注解可以确保在应用中已存在相同类型的 Bean 时,自动配置不会再创建新的 Bean,从而避免重复配置。

4. 文档和示例

为你的自定义 starter 或自动配置提供详细的文档和使用示例。这对于其他开发者来说是非常有价值的,特别是在解决依赖和配置问题时。

5. 分离自动配置和业务逻辑

将自动配置代码和业务逻辑代码分开,自动配置模块不应包含业务逻辑,它只应负责自动装配和条件判断。这样做可以提高模块的清晰度和重用性。

总结

Spring Boot 的 SPI 机制不仅强化了框架的自动配置能力,还提供了一种灵活且强大的方式来扩展和定制应用程序的行为。通过合理利用这一机制,开发者可以显著简化 Spring 应用的配置过程,加速开发和部署周期。

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

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

相关文章

扩展学习|一文读懂知识图谱

一、知识图谱的技术实现流程及相关应用 文献来源&#xff1a;曹倩,赵一鸣.知识图谱的技术实现流程及相关应用[J].情报理论与实践,2015, 38(12):127-132. &#xff08;一&#xff09;知识图谱的特征及功能 知识图谱是为了适应新的网络信息环境而产生的一种语义知识组织和服务的方…

HarmonyOS开发案例:【卡片二级联动】

1 卡片介绍 使用ArkTS语言&#xff0c;实现一个导航与内容二级联动的效果。 2 标题 二级联动&#xff08;ArkTS&#xff09; 3 介绍 介绍了如何基于List组件实现一个导航和内容的二级联动效果。样例主要包含以下功能&#xff1a; 切换左侧导航&#xff0c;右侧滚动到对应…

自定义类型②③——联合体和枚举

自定义类型②③——联合体和枚举 1.联合体1.1 联合体类型的声明1.2 联合体的特点1.3 相同成员结构体和联合体的对比1.4 联合体大小的计算1.5 联合体的应用①1.5 联合体的应用② 2. 枚举2.1 枚举类型的声明2.2 枚举类型的特点2.3 枚举的优点 1.联合体 1.1 联合体类型的声明 关…

Python sqlite3库 实现 数据库基础及应用 输入地点,可输出该地点的爱国主义教育基地名称和批次的查询结果。

目录 【第11次课】实验十数据库基础及应用1-查询 要求: 提示: 运行结果&#xff1a; 【第11次课】实验十数据库基础及应用1-查询 声明&#xff1a;著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 1.简答题 数据库文件Edu_Base.db&#…

有什么方便的教学口语软件?6个软件教你快速练习口语

有什么方便的教学口语软件&#xff1f;6个软件教你快速练习口语 以下是六个方便实用的教学口语软件&#xff0c;它们可以帮助您快速练习口语&#xff1a; AI外语陪练: 这是一款知名的语言学习软件&#xff0c;提供多种语言的口语练习课程。它采用沉浸式的学习方法&#xff0…

【数字图像处理笔记】Matlab实现图像平滑算法 均值-中值-高斯滤波 (三)

&#x1f48c; 所属专栏&#xff1a;【数字图像处理笔记】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x…

jetson实操(二):jetson nano发送短信到指定用户

文章目录 一、准备工作二、代码实现 一、准备工作 腾讯云网址&#xff1a;点击 注&#xff1a;需先申请“短信签名”和“短信正文”&#xff0c;按照要求填写申请即可&#xff0c;腾讯云的审核效率还是很快的&#xff0c;一般在1-2个小时内就会有结果&#xff0c;链接&…

2024-2034年,量子密码市场年增长率将达29.3%

Visiongain发布了一份新报告&#xff0c;题为《2024-2034年量子密码市场报告》&#xff1a;按组件&#xff08;软件、硬件&#xff09;、软件&#xff08;加密算法、密钥管理解决方案等&#xff09;、硬件&#xff08;量子密钥分发&#xff08;QKD&#xff09;设备、量子随机数…

CkickHouse JDBC 使用整理

1. pom 引入 <dependency><groupId>com.clickhouse</groupId><artifactId>clickhouse-jdbc</artifactId><version>0.4.6</version></dependency><dependency><groupId>org.roaringbitmap</groupId><arti…

BeautifulSoup库TapTap评论爬虫

最近在写关于评论数据主题建模和情感分析的作业&#xff0c;本来想用八爪鱼直接爬TapTap的评论数据&#xff0c;但是自动识别网页总是定位错误&#xff0c;还是回归BeautifulSoup和Request来进行评论内容的爬取&#xff0c;具体操作步骤如下 导入所需的库 import re import r…

定制旁通式孔板流量计需要哪些技术参数

旁通式孔板流量计又称桥式孔板流量计&#xff0c;本产品含有直管&#xff0c;直管中安装有孔板&#xff0c;该孔板两侧的直管壁上分别设置一个测量管&#xff0c;其特征是&#xff1a;所述直管和一个桥管并联式连接&#xff0c;二者内管相互连通&#xff0c;并且所述直管和桥管…

mars3d的config,json文件配置谷歌影像地图的tilingScheme属性

mars3d的config,json文件配置tilingScheme属性说明&#xff1a; 1.cesium加载谷歌影像地图的时候需要配置tilingScheme参数&#xff0c;如以下代码&#xff1a; var viewer new Cesium.Viewer("cesiumContainer", { animation: false, //是否显示动画控件 baseLaye…

64位Office API声明语句第118讲

跟我学VBA&#xff0c;我这里专注VBA, 授人以渔。我98年开始&#xff0c;从源码接触VBA已经20余年了&#xff0c;随着年龄的增长&#xff0c;越来越觉得有必要把这项技能传递给需要这项技术的职场人员。希望职场和数据打交道的朋友&#xff0c;都来学习VBA,利用VBA,起码可以提高…

文件夹加密软件哪个好?文件夹加密软件排行榜

许多人给小编说&#xff0c;我们公司想实现文件私自发出呈乱码状态&#xff0c;这说明公司逐渐认识到文件加密的重要性。 目前&#xff0c;加密软件已经广泛应用于企业办公、商业贸易、个人应用等多个领域&#xff0c;成为保护数据安全和隐私的重要手段。 为了保护企业机密&am…

【driver2】设备读写,同步和互斥,ioctl,进程休眠,时间和延时,延缓

文章目录 1.实现设备读写&#xff1a;write函数中一个进程写没问题&#xff0c;两进程写&#xff1a;第一个进程运行到kzalloc时&#xff0c;第二个进程也执行了kzalloc&#xff0c;只第二个进程地址保存在c中&#xff0c;第一个进程分配内存空间地址丢失造成内存泄漏。第一个进…

sqlalchemy 分表实现方案

1.需求及场景概述 现有系统中因历史数据量过大,产生了将历史数据进行按月存储的要求,系统和数据库交互使用的是sqlalchemy,假设系统的原来的历史记录表(record)如下: 为了将历史数据按月分表存储,我们需要以此表为基础按月创建对应的月表来进行分表存储,同时又要使用or…

学华为沟通,汇总5大项目沟通技巧

高效沟通在项目管理中的重要性不容小觑&#xff0c;它是确保项目顺利进行、提升团队协作效率、实现项目目标的关键因素。如果沟通不畅&#xff0c;往往容易导致成员对项目目标理解不一致&#xff0c;或信息传递不及时不准确&#xff0c;导致项目工作方向偏差&#xff0c;增加项…

前端工程化05-初始前端工程化Node基本介绍安装配置基础知识

6、初始前端工程化 6.1、工程化概述 虽然前几篇我的目录标题写的前端工程化&#xff0c;但是那些东西并不属于前端工程化的内容&#xff0c;更倾向于是js、jq当中的东西&#xff0c;下面我们将接触真正的前端工程化。 前端工程化开发其实现在是离不开一个东西的&#xff0c;…

Matlab 手写板设计

1、介绍 MATLAB手写板可以作为一个很好的数据输入口&#xff0c;其可以获取该手写板上任意字母、数字&#xff0c;甚至可以制作样本数据。具体用途体现在如下几方面&#xff1a; 数学公式输入&#xff1a;手写板允许用户直接用手写方式输入复杂的数学公式&#xff0c;这对于使…

电子书制作神器,简单操作

​随着数字化时代的到来&#xff0c;电子书籍越来越受到人们的喜爱。而一款优秀的电子翻页书制作软件&#xff0c;则能够帮助你轻松制作出专业级的电子书&#xff0c;让你的阅读体验更加丰富多彩。 今天&#xff0c;我们就来为大家推荐一款优秀的电子翻页书制作软件——FLBOOK在…