SpringBoot3自动配置流程 SPI机制 核心注解 自定义starter

1. 自动配置流程

  1. 导入starter
  2. 依赖导入autoconfigure
  3. 寻找类路径下 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件
  4. 启动,加载所有 自动配置类 xxxAutoConfiguration
    1. 给容器中配置功能组件
    2. 组件参数绑定到 属性类中。xxxProperties
    3. 属性类配置文件前缀项绑定
    4. @Contional派生的条件注解进行判断是否组件生效

所有场景自动配置好可以直接使用,修改配置文件,就会修改底层参数,例如:通过修改yaml配置server.port,就可以修改tomcat运行端口,注入SpringBoot配置好的组件可以随时使用。

2. SPI机制

  • Java中的SPI(Service Provider Interface)是一种软件设计模式用于 在应用程序中动态地发现和加载组件 。SPI的思想是,定义一个接口或抽象类,然后通过在classpath中定义实现该接口的类来实现对组件的动态发现和加载。
    SPI的主要目的是解决在应用程序中使用 可插拔组件 的问题。例如,一个应用程序可能需要使用不同的日志框架或数据库连接池,但是这些组件的选择可能取决于运行时的条件。通过使用SPI,应用程序可以在运行时发现并加载适当的组件,而无需在代码中硬编码这些组件的实现类。
    在Java中,SPI的实现方式是通过在META-INF/services目录下创建一个以服务接口全限定名为名字的文件,文件中包含实现该服务接口的类的全限定名。当应用程序启动时,Java的SPI机制会自动扫描classpath中的这些文件,并根据文件中指定的类名来加载实现类。
    通过使用SPI,应用程序可以实现更灵活、可扩展的架构,同时也可以避免硬编码依赖关系和增加代码的可维护性。

在SpringBoot中,文件位置位于:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

场景:抽取聊天机器人场景,它可以打招呼.
效果:任何项目导入此starter都具有打招呼功能,并且问候语中的人名需要可以在配置文件中修改

  1. 创建自定义starter项目,引入spring-boot-starter基础依赖
  2. 编写模块功能,引入模块所有需要的依赖。
  3. 编写xxxAutoConfiguration自动配置类,帮其他项目导入这个模块需要的所有组件
  4. 编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports指定启动需要加载的自动配置
  5. 其他项目引入即可使用

3. @EnableXxxx 功能开关

自动配置,项目一启动,SPI文件中指定的所有类都会加载。通过@EnableXxxx手动控制哪些功能的开启; 手动导入。都是利用 @Import 把此功能要用的组件导入进去。

4. SpringBoot核心注解

1. @SpringBootApplication

@SpringBootConfiguration

就是: @Configuration ,容器中的组件,配置类。spring ioc启动就会加载创建这个类对象

@EnableAutoConfiguration:开启自动配置

开启自动配置

@AutoConfigurationPackage:扫描主程序包:加载自己的组件

  • 利用 @Import(AutoConfigurationPackages.Registrar.class) 想要给容器中导入组件。
  • 把主程序所在的包的所有组件导入进来。

@Import(AutoConfigurationImportSelector.class):加载所有自动配置类:加载starter导入的组件

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector:

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {List<String> configurations = ImportCandidates.load(AutoConfiguration.class, getBeanClassLoader()).getCandidates();Assert.notEmpty(configurations,"No auto configuration classes found in "+ "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports. If you "+ "are using a custom packaging, make sure that file is correct.");return configurations;}

扫描SPI文件:META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

@ComponentScan

组件扫描:排除一些组件(哪些不要)
排除前面已经扫描进来的配置类、和自动配置类。

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })

2. 完整启动加载流程

在这里插入图片描述

5. 自定义starter

1. 创建robot-boot-starter模块

这个模块作为公有的聊天机器人模块,也就是有很多项目模块都需要引入它

引入依赖

<parent><artifactId>spring-boot-starter-parent</artifactId><groupId>org.springframework.boot</groupId><version>3.0.5</version>
</parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.projectlombok/lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.10</version><scope>provided</scope></dependency><!--        导入配置处理器,配置文件自定义的properties配置都会有提示--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional></dependency>
</dependencies>

自定义配置有提示。导入以下依赖重启项目,再写配置文件就有提示

@ConfigurationProperties(prefix = "robot", ignoreInvalidFields = true)  //此属性类和配置文件指定前缀绑定
@Component
@Data
public class RobotProperties {private String name;
}
<!--        导入配置处理器,配置文件自定义的properties配置都会有提示-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>
@Service
public class RobotService {@Autowiredprivate RobotProperties robotProperties;public String hello(){return "你好," + robotProperties.getName();}
}

2. 创建spring-user模块

引入聊天机器人模块(robot-boot-starter)

<dependency><groupId>org.robot</groupId><artifactId>robot-boot-starter</artifactId><version>1.0-SNAPSHOT</version>
</dependency>
@RequestMapping(value = "/user")
@RestController
public class UserController {//这个组件是在robot-boot-starter模块中定义的@Autowiredprivate RobotController robotController;public String robot(){return robotController.hello();}
}

yml配置

robot:name: chatgpt

6. 如何在业务模块中实现公有模块中的组件注册

方式一(指定包扫描)

Spring默认只扫描启动类目录下和子包下边的组件,所以这里要指定扫描robot-boot-starter

@ComponentScan(value = {"org.robot"}) //扫描机器人模块下的组件
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}

方式二(XxxAutoConfiguration)

robot-boot-starter模块写一个RobotAutoConfiguration,给容器中导入这个场景需要的所有组件

@Import({RobotController.class, RobotProperties.class, RobotService.class})
public class RobotAutoConfiguration {
}

spring-user模块中,导入RobotAutoConfiguration.class

@Import(RobotAutoConfiguration.class)
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}

方式三(@EnableXxx)

使用@EnableXxx机制,只要使用这个注解 就会开启这个功能

robot-boot-starter模块自定义@EnableRobot注解

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
//以上元注解直接找个@EnableXxx类 拷贝进来即可
@Import(RobotAutoConfiguration.class)
public @interface EnableRobot {}

spring-user模块中启用注解,相当于导入了RobotAutoConfiguration.class中导入的组件

@EnableRobot
@SpringBootApplication
public class UserApplication {public static void main(String[] args) {SpringApplication.run(UserApplication.class, args);}
}

别人引入starter需要使用 @EnableRobot开启功能,灵活配置

方式四(完全自动配置)

  • 依赖SpringBoot的SPI机制
  • META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中编写好我们自动配置类的全类名即可
  • 项目启动,自动加载我们的自动配置类

robot-boot-starter类路径下新建META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,里边放入指定要扫描的配置类

org.robot.config.RobotAutoConfiguration

这样只要别的项目引入了robot-boot-starter模块,里边的组件都会自动注入

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端技术Vue学习笔记--001

前端技术Vue学习笔记 文章目录 前端技术Vue学习笔记1、Vue2和Vue3比较2、Vue简介3、Vue快速上手4、插值表达式{{}}5、Vue响应式特性6、Vue指令6.1、v-html指令6.2、v-show指令和v-if指令6.3、v-else指令和v-else-if指令6.4、v-on指令6.4.1、v-on指令基础6.4.2、v-on调用传参 6.…

Kubernetes_核心组件_kubelet_kubelet服务全解析(二)

文章目录 前言kubelet 架构kubelet 职责Node管理(节点管理)Pod管理 kubelet管理Podkubelet如何管理当前节点上所有Podkubelet三个端口kubelet获取Pod清单kubelet通过CRI接口管理Pod以及里面的容器 PodWorker的工作细节PodWorker的工作细节PLEG组件PLEG报错 kubelet创建并启动Po…

arcgis-利用等高线数据生成dem栅格

1、打开cass&#xff0c;展高程点&#xff0c;绘制三角网&#xff0c;绘制等高线&#xff0c;删除三角网和高程点。如下&#xff1a; 2、得到的等高线图&#xff0c;如下&#xff1a; 3、保存文件为dwg格式&#xff0c;随后打开arcmap软件&#xff0c;打开dwg的线层数据&#x…

Linux yum 运行时提示编码问题错误

报错&#xff1a; UnicodeWarning: Unicode equal comparison failed to convert both arguments to Unicode - interpreting them as being unequal 解决&#xff1a; 这个报错是编码问题导致的 在文件头加上 # -*- coding:utf-8 -*- 对需要比较的中文字符变量如&#xff…

网络安全防御篇之安全问题及防火墙简介

网络安全常识及术语 网络的脆弱性 什么样的网络是安全的

单片机_按键——单击,双击,长按

#define KEY_DOWN_return 1 //单击 #define KEY_Double_return 2 //双击 #define KEY_Long_return 3 //长按 #define KEY_LONG_FREE_return 6 //长按结束#define double_time_MIN 80 //双击按键,在这个时间范围内,按下两次则认为有…

Java当中的深拷贝和浅拷贝

文章目录 一、前提二、浅拷贝1. BeanUtils实现浅拷贝 三、深拷贝1. 实现Cloneable接口并重写clone()方法&#xff1a;2. 使用序列化与反序列化&#xff1a; 一、前提 在计算机的内存中&#xff0c;每个对象都被赋予一个地址&#xff0c;该地址指向对象在内存中存储的位置。当我…

数据结构和算法解析:排序问题简易总结

直接插入排序 直接插入排序&#xff08;Straight Insertion Sorting&#xff09;的基本思想&#xff1a;在要排序的一组数中&#xff0c;假设前面(n-1) [n>2] 个数已经是排好顺序的&#xff0c;现在要把第n个数插到前面的有序数中&#xff0c;使得这n个数也是排好顺序的。如…

centos7部署websocket

django项目&#xff0c;中间使用websocket进行通讯&#xff0c;想部署到服务器上&#xff0c;按照之前部署项目的思路进行部署&#xff0c;但是失败了。解决了一下&#xff0c;在此记录。 主项目下有一子app&#xff0c;一模版文件&#xff0c;一静态文件。项目中主要用到dweb…

Factorization Machines(论文笔记)

样例一&#xff1a; 一个简单的例子,train是一个字典&#xff0c;先将train进行“one-hot” coding&#xff0c;然后输入相关特征向量&#xff0c;可以预测相关性。 from pyfm import pylibfm from sklearn.feature_extraction import DictVectorizer import numpy as np tra…

【MATLAB第59期】基于MATLAB的混沌退火粒子群CSAPSO-BP、SAPSO-BP、PSO-BP优化BP神经网络非线性函数拟合预测/回归预测对比

【MATLAB第59期】基于MATLAB的混沌退火粒子群CSAPSO-BP、SAPSO-BP、PSO-BP优化BP神经网络非线性函数拟合预测/回归预测对比 注意事项 不同版本matlab 不同电脑 加上数据集随机&#xff0c;BP权值阈值随机&#xff0c;进化算法种群随机&#xff0c;所以运行结果不一定和我运行…

集成了32位Cortex®M0内核XMC1302T038X0200AB、XMC1302Q040X0200AB 32MHz 200KB 闪存 工业MCU

XMC1000 32位工业 MCU 将 ARM Cortex™-M0 核心与领先的 65nm 制造工艺相结合&#xff0c;克服了目前 8 位设计的局限。XMC1000系列让目前的 8 位用户有机会享受 32 位的功耗&#xff0c;同时不在价格或易用性上做出妥协。XMC1000 在其细分市场提供最为广泛的闪存产品线&#x…

3分钟,快速上手Postman接口测试

Postman是一个用于调试HTTP请求的工具&#xff0c;它提供了友好的界面帮助分析、构造HTTP请求&#xff0c;并分析响应数据。实际工作中&#xff0c;开发和测试基本上都有使用Postman来进行接口调试工作。有一些其他流程的工具&#xff0c;也是模仿的Postman的风格进行接口测试工…

下载|GitLab 2023 年 DevSecOps 全球调研报告:安全左移深入人心、AI/ML 蔚然成风

目录 谁应该对应用程序安全负主要责任&#xff1f; 安全实践的最大挑战 AI 驱动研发&#xff0c;提升研发效率 各个角色使用的工具数量是多少&#xff1f; 一体化 DevSecOps 平台有哪些优势&#xff1f; 56%、74%、71%、65%、57% 这些数字和 DevSecOps 结合在一起&#xf…

android adb命令获取处于当前屏幕的Activity

android adb命令获取处于当前屏幕的Activity 使用adb命令&#xff1a; adb shell dumpsys activity activities 输出&#xff0c;例如: ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities) Display #0 (activities from top to bottom): * Task{38ef601 #5281 typ…

Java当中的栈

栈的理解 栈&#xff08;Stack&#xff09;是一种受限的线性数据结构&#xff0c;所谓受限是指栈只暴露栈顶和栈底的操作&#xff0c;其底层是由数组实现的。栈的特性是先进后出。 常用方法 注意上面的peek()方法和pop()方法的区别&#xff01; 实例 import java.util.Stack…

grpc中间件之链路追踪(otel+jaeger)

参考文档 https://github.com/grpc-ecosystem/go-grpc-middleware/blob/main/examples/client/main.go https://github.com/grpc-ecosystem/go-grpc-middleware/blob/main/examples/server/main.go https://github.com/open-telemetry/opentelemetry-go/blob/main/example/jaeg…

【Rust 基础篇】Rust 通道实现单个消费者多个生产者模式

导言 在 Rust 中&#xff0c;我们可以使用通道&#xff08;Channel&#xff09;来实现单个消费者多个生产者模式&#xff0c;简称为 MPMC。MPMC 是一种常见的并发模式&#xff0c;适用于多个线程同时向一个通道发送数据&#xff0c;而另一个线程从通道中消费数据的场景。本篇博…

搭建elasticsearch过程中遇到问题记录

##1.新建用户 解压es之前&#xff0c;新建用户做后续操作&#xff0c;root用户无法启动es。 ##2.增大普通用户可打开最大文件数 ##3.增大普通用户可启动线程数 ##4.增大用户可使用虚拟内存 编辑 /etc/sysctl.conf&#xff0c;追加以下内容&#xff1a; vm.max_map_count262144…

sql中group by 的使用

1、概述 Group By 从字面意义上理解就是根据By指定的规则对数据进行分组&#xff0c;所谓的分组就是将一个数据集划分为若干个小区域&#xff0c;然后针对若干个小区域进行数据处理 2、原始表 3、简单的Group By 示例1 select 类别&#xff0c;数量 as 数量之和 from A gro…