如何创建自己的 Spring Boot Starter 并为其编写单元测试
当我们想要封装一些自定义功能给别人使用的时候,创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话,本文将带你一起创建一个自己的Spring Boot Starter。
快速入门
-
创建一个新的 Maven 项目。第三方封装的命名格式是
xxx-spring-boot-starter,例如:didispace-spring-boot-starter。 -
编辑
pom.xml,添加spring-boot-autoconfigure和spring-boot-starter依赖
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-autoconfigure</artifactId></dependency>
</dependencies>
-
创建一个用
@Configuration注释的配置类,在这里您可以使用@Bean来创建使用@ConditionalOnClass、@ConditionalOnMissingBean等条件注释来控制何时应用配置。
@Configuration
@ConditionalOnClass(MyFeature.class)
@ConditionalOnProperty(prefix = "myfeature", name = "enabled", matchIfMissing = true)
public class MyFeatureAutoConfiguration {@Bean@ConditionalOnMissingBeanpublic MyFeature myFeature() {return new MyFeature();}
}
-
在
src/main/resources/META-INF目录下创建spring.factories文件,并在org.springframework.boot.autoconfigure.EnableAutoConfiguration关键字下列出您的自动配置类,比如:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.didispace.myfeature.MyFeatureAutoConfiguration
该配置的作用是让Spring Boot应用在引入您自定义Starter的时候可以自动这里的配置类。
注意:Spring Boot 2.7开始,不再推荐使用
spring.factories,而是改用/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports,文件内容直接放需要自动加载配置类路径即可。这个变更具体可见之前的这篇文章:《Spring Boot 2.7开始spring.factories不推荐使用了》:https://www.didispace.com/article/spring-boot/spring-boot-factories-deprecations.html
验证测试
在制作Spring Boot Starter的时候,一定记得使用单元测试来验证和确保自动化配置类在任何条件逻辑在启动器下能够按照正确的预期运行。
创建单元测试
使用@SpringBootTest加载完整的应用程序上下文,并验证启动程序是否正确配置了 Bean 和属性。
@SpringBootTest(classes = TestApplication.class)
public class MyStarterAutoConfigurationTest {@Autowired(required = false)private MyService myService;@Testpublic void testMyServiceAutoConfigured() {assertNotNull(myService, "MyService should be auto-configured");}
}
覆盖不同的配置
如果有不同的配置方案,那么还需要使用@TestPropertySource或@DynamicPropertySource覆盖属性以测试不同配置下的情况。
或者也可以直接简单的通过@SpringBootTest中的属性来配置,比如下面这样:
@SpringBootTest(properties = "my.starter.custom-property=customValue")
public class MyStarterPropertiesTest {@Value("${my.starter.custom-property}")private String customProperty;@Testpublic void testPropertyOverride() {assertEquals("customValue", customProperty, "Custom property should be overridden by @SpringBootTest");}
}
覆盖@Conditional的不同分支
如果您的启动器包含条件配置,比如:@ConditionalOnProperty、@ConditionalOnClass等注解,那么就必须编写测试来覆盖所有条件以验证是否已正确。
比如下面这样:
@SpringBootTest(classes = {TestApplication.class, MyConditionalConfiguration.class})
@ConditionalOnProperty(name = "my.starter.enable", havingValue = "true")
public class MyStarterConditionalTest {@Autowiredprivate ApplicationContext context;@Testpublic void conditionalBeanNotLoadedWhenPropertyIsFalse() {assertFalse(context.containsBean("conditionalBean"),"Conditional bean should not be loaded when 'my.starter.enable' is false");}
}
为了覆盖不同的条件分支,我们通常还需要使用@TestConfiguration注解来有选择地启用或禁用某些自动配置。
相关文章:
如何创建自己的 Spring Boot Starter 并为其编写单元测试
当我们想要封装一些自定义功能给别人使用的时候,创建Spring Boot Starter的形式是最好的实现方式。如果您还不会构建自己的Spring Boot Starter的话,本文将带你一起创建一个自己的Spring Boot Starter。 快速入门 创建一个新的 Maven 项目。第三方封装的…...
C++ :STL中deque的原理
deque的结构类似于哈希表,使用一个指针数组存储固定大小的数组首地址,当数据分布不均匀时将指针数组内的数据进行偏移,桶不够用的时候会像vector一样扩容然后将之前数组中存储的指针拷贝过来,从原理可以看出deque的性能是非常高的…...
AttributeError: ‘Namespace‘ object has no attribute ‘EarlyStopping‘
报错原因 这个报错信息表明在Python脚本train.py中尝试访问命令行参数args.EarlyStopping时出错,具体错误是AttributeError: Namespace对象没有名为EarlyStopping的属性。 在Python的argparse模块中,当我们通过命令行传递参数并解析时,解析…...
深度学习pytorch——卷积神经网络(持续更新)
计算机如何解析图片? 在计算机的眼中,一张灰度图片,就是许多个数字组成的二维矩阵,每个数字就是此点的像素值(图-1)。在存储时,像素值通常位于[0, 255]区间,在深度学习中࿰…...
【edge浏览器无法登录某些网站,以及迅雷插件无法生效的解决办法】
edge浏览器无法登录某些网站,以及迅雷插件无法生效的解决办法 edge浏览器无法登录某些网站,但chrome浏览器可以登录浏览器插件无法使用,比如迅雷如果重装插件重装浏览器重装迅雷后仍然出现问题 edge浏览器无法登录某些网站,但chro…...
OpenHarmony无人机MAVSDK开源库适配方案分享
MAVSDK 是 PX4 开源团队贡献的基于 MavLink 通信协议的用于无人机应用开发的 SDK,支持多种语言如 C/C、python、Java 等。通常用于无人机间、地面站与通信设备的消息传输。 MAVLink 是一种非常轻量级的消息传递协议,用于与无人机(以及机载无…...
模型训练----parser.add_argument添加配置参数
现在需要配置参数来达到修改训练的方式,我现在需要新建一个参数来开关wandb的使用。 首先就是在def parse_option():函数里添加上你要使用的变量名 parser.add_argument("--open_wandb",type bool,defaultFalse,helpopen wandb) 到config文件里增加你的…...
数字未来:探索 Web3 的革命性潜力
在当今数字化的时代,Web3作为互联网的新兴范式正逐渐崭露头角,引发了广泛的关注和探讨。本文将深入探索数字未来中Web3所蕴含的革命性潜力,探讨其对社会、经济和技术的深远影响。 1. Web3:数字世界的下一个阶段 Web3是一个正在崛…...
群晖NAS使用Docker部署大语言模型Llama 2结合内网穿透实现公网访问本地GPT聊天服务
文章目录 1. 拉取相关的Docker镜像2. 运行Ollama 镜像3. 运行Chatbot Ollama镜像4. 本地访问5. 群晖安装Cpolar6. 配置公网地址7. 公网访问8. 固定公网地址 随着ChatGPT 和open Sora 的热度剧增,大语言模型时代,开启了AI新篇章,大语言模型的应用非常广泛,包括聊天机…...
[选型必备基础信息] 存储器
存储芯片根据断电后是否保留存储的信息可分为易失性存储芯片(RAM)和非易失性存储芯片(ROM)。 简单说,存储类IC分为 ROM和RAM ROM:EEPROM / Flash / eMMC RAM:SRAM/SDRAM/DDR2/DDR3/DDR4/DDR5…...
C++——C++11线程库
目录 一,线程库简介 二,线程库简单使用 2.1 传函数指针 编辑 2.2 传lamdba表达式 2.3 简单综合运用 2.4 线程函数参数 三,线程安全问题 3.1 为什么会有这个问题? 3.2 锁 3.2.1 互斥锁 3.2.2 递归锁 3.3 原子操作 3…...
机器学习 | 线性判别分析(Linear Discriminant Analysis)
1 机器学习中的建模 1.1 描述性建模 以方便的形式给出数据的主要特征,实质上是对数据的概括,以便在大量的或有噪声的数据中仍能观察到重要特征。重在认识数据的主要概貌,理解数据的重要特征。 Task:聚类分析,数据降…...
TypeScript-数组、函数类型
1.数组类型 1.1类型 方括号 let arry:number[][5,2,0,1,3,1,4] 1.2 数组泛型 let arry2:Array<number>[5,2,0,1,3,1,4] 1.3接口类型 interface makeArryRule{[index:number]:number }let arry3:makeArryRule[5,2,0,1,3,1,4] 1.4伪数组 说明: argument…...
Python深度学习034:cuda的环境如何配置
文章目录 1.安装nvidia cuda驱动CMD中看一下cuda版本:下载并安装cuda驱动2.创建虚拟环境并安装pytorch的torch_cuda3.测试附录1.安装nvidia cuda驱动 CMD中看一下cuda版本: 注意: 红框的cuda版本,是你的显卡能装的最高的cuda版本,所以可以选择低于它的版本。比如我的是11…...
【论文笔记】Text2QR
论文:Text2QR: Harmonizing Aesthetic Customization and Scanning Robustness for Text-Guided QR Code Generation Abstract 二维码通常包含很多信息但看起来并不美观。stable diffusion的出现让平衡扫描鲁棒性和美观变为可能。 为了保证美观二维码的稳定生成&a…...
【ReadPapers】A Survey of Large Language Models
LLM-Survey的llm能力和评估部分内容学习笔记——思维导图 思维导图 参考资料 A Survey of Large Language Models论文的github仓库...
站群CMS系统
站群CMS系统是一种用于批量建立和管理网站的内容管理系统,它能够帮助用户快速创建大量的网站,并实现对这些网站的集中管理。以下是三个在使用广泛的站群CMS系统,它们各具特色,可以满足不同用户的需求。 1. Z-BlogPHP Z-BlogPHP是…...
landsat8数据产品说明
1、下载数据用户手册 手册下载网址,搜索landsat science关键词,并点击到官网下载。 2、用户手册目录 3、landsat8数据产品说明 具体说明在手册的第四章,4.1.4数据产品章节,具体描述如下: 英文意思: L8 的…...
Golang 内存管理和垃圾回收底层原理(二)
一、这篇文章我们来聊聊Golang内存管理和垃圾回收,主要注重基本底层原理讲解,进一步实战待后续文章 垃圾回收,无论是Java 还是 Golang,基本的逻辑都是基于 标记-清理 的, 标记是指标记可能需要回收的对象,…...
OpenHarmony:全流程讲解如何编写ADC平台驱动以及应用程序
ADC(Analog to Digital Converter),即模拟-数字转换器,可将模拟信号转换成对应的数字信号,便于存储与计算等操作。除电源线和地线之外,ADC只需要1根线与被测量的设备进行连接。 一、案例简介 该程序是基于…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
