自定义Spring Boot Starter

引言

在Spring Boot的世界中,Starter 能够简化我们的开发过程,通过封装常见的依赖和自动配置。本篇旨在为有志于进一步简化Spring Boot应用配置的开发者提供指导,让我们一起创建一个自定义的Spring Boot Starter。

一、什么是 Spring Boot Starter?

Starter是Spring Boot中的一个核心概念,它是一种依赖描述符,用于简化Maven或Gradle项目中的依赖管理和自动配置。Starter通常包含一组预定义的依赖项和一个或多个自动配置类,它们可以帮助开发人员快速启动和运行一个特定类型的应用程序。

Starter的工作原理如下:
  • 依赖管理:Starter通过将常用库和框架组织在一起,简化了项目的依赖声明。例如,如果一个项目需要使用Spring MVCJackson JSON库,只需添加spring-boot-starter-web依赖即可,无需手动添加Spring MVC和其他相关依赖。
  • 自动配置:Starter中的自动配置类会根据项目的依赖关系和属性设置自动应用最佳实践配置。这些自动配置类通常位于org.springframework.boot.autoconfigure包中。例如,当添加spring-boot-starter-web依赖时,Spring
    Boot会自动配置嵌入式Tomcat服务器和Spring MVC相关的组件。
  • 约定优于配置:Starter遵循Spring Boot的核心原则之一,即“约定优于配置”。这意味着,除非明确指定,否则默认配置将应用于项目。这有助于减少不必要的配置,并使项目更易于维护。
Spring Boot如何使用Starter来简化项目配置:
  • 选择适当的Starter:根据项目需求,从Spring Boot提供的众多Starter中选择合适的依赖。例如,对于Web应用程序,可以添加spring-boot-starter-web;对于数据访问,可以添加spring-boot-starter-data-jpa等。
  • 添加依赖:在项目的构建配置文件(如pom.xml或build.gradle)中添加所选Starter的依赖。
  • 自定义配置(可选):虽然Starter提供了许多默认配置,但开发人员仍然可以根据需要自定义这些配置。这可以通过在项目的配置文件(如application.propertiesapplication.yml)中覆盖默认值来实现。
  • 编写业务代码:在Starter的帮助下,开发人员可以将更多精力投入到业务代码的编写上,而不是关注底层的配置细节。

二、自定义 Starter 的动机

  • 特定领域的需求:当你的项目或产品需要针对特定领域进行优化,而现有的Starter无法满足这些需求时,创建自定义Starter就变得很有必要。例如你的公司可能有一套特定的日志记录策略,或者需要集成一个特殊的安全框架,而这些都不是通用的Starter所能提供的。
  • 封装复杂性:如果项目中有一些复杂的配置或组件集成,而这些配置经常需要在多个项目中重复使用,那么通过创建一个自定义Starter来封装这些复杂性,可以避免在每个项目中重复相同的配置代码,提高开发效率。
  • 促进代码复用:在大型组织或企业中,可能有多个团队在不同的项目中工作。如果这些项目有共同的技术栈或依赖需求,创建一个自定义Starter可以帮助各个团队共享复用代码,减少重复劳动。
  • 遵循最佳实践:有时候,组织内部可能已经形成了一套开发最佳实践,通过创建一个自定义Starter,可以将这些最佳实践固化并自动应用到所有新项目中,确保开发质量和一致性。
  • 提供更好的开发者体验:自定义Starter可以为开发者提供更加友好的开发体验,例如通过简化配置流程提供清晰的文档示例代码,使得新加入项目的开发者能够更快地上手.

三、创建自定义 Starter

新建一个普通Maven项目:yu-spring-boot-starter

① 编写启动器

在这里插入图片描述

② 导入依赖
 <!-- 引入Spring Boot自动配置依赖 ,用于自动配置应用程序的各种组件和功能.自定义starter时必须要有 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

<!-- 引入Spring Boot配置处理器,自定义starter时,调用方的配置文件中可以给出提示信息(如不引用,则不会提示,此包非必须) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <!-- 表示两个项目之间依赖不传递:不设置optional或者optional是false,表示传递依赖;当出现依赖冲突时候,会自动剔除该依赖- -->
    <optional>true</optional>
</dependency>
③ 添加属性类

如果你的Starter需要一些配置属性,你可以创建一个属性类来绑定这些属性。创建一个新的Java类,并使用@ConfigurationProperties注解标记它为属性类。在该类中,定义你需要的属性,并提供相应的gettersetter方法。

/**
 * 将配置文件中以 "yu" 为前缀的属性值绑定到此Java类上
 * starter被引用时,会将驼峰命名的参数名称转化为全小写,并在原大写的前面添加"-",
 * 如本类的userName属性,yu.user-name来进行展现
 */
@ConfigurationProperties(prefix = "yu")
public class User {
    private String userName;
    private String userPassword;
	//省略get/set...
}

④ 添加一个业务类

定义一个业务类,编写核心业务流程

public class UserServiceImpl {
    @Autowired
    private User user;
    public String getUserInfo() {
        return user.getUserName() + "_" + user.getUserPassword();
    }
}

⑤ 自定义属性配置

需要创建一个自动配置类,用于配置和初始化我们的Starter。创建一个新的Java类,并使用@Configuration注解标记它为配置类。

@Configuration	// 表示这个类为配置类
@EnableConfigurationProperties(User.class)	// 启用 User 类的配置属性
public class YuStarterAutoConfiguration {
    // 在这里定义你要注册的对象
    @Bean
    @ConditionalOnClass(UserServiceImpl.class)		// 只有当指定的类存在于类路径中时,才会创建该方法返回的 Bean
    public UserServiceImpl serviceStarterTest() {
        return new UserServiceImpl();
    }
}
⑥ 添加需要自动配置的配置类信息

在resources编写一个自己的 META-INF\spring.factories

# 自动配置,如果有多个配置则使用",\"结尾的方式即可
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.yu.config.YuStarterAutoConfiguration
⑦ 编译打包

maven–>clear–>install即可
在这里插入图片描述

⑧ 引用

新建一个SpringBoot 项目,导入我们自己写的启动器

<dependency>
    <groupId>com.yu</groupId>
    <artifactId>yu-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

编写一个 HelloController 进行测试我们自己的写的接口!

@RestController
@RequestMapping("test")
public class UserTestController {
    @Autowired
    private UserServiceImpl userService;
    @RequestMapping("starter")
    @ResponseBody
    public String starter() {
        return userService.getUserInfo();
    }
}

编写配置文件 application.properties

yu.user-name=https://blog.csdn.net/m0
yu.user-password=53127626

启动项目进行测试,结果成功 !

https://blog.csdn.net/m0_53127626

在这里插入图片描述

四、总结

本文详细介绍如何自定义一个Spring Boot Starter。通过自定义Starter,我们可以将一些通用的功能封装起来,提高代码的复用性和可维护性。


希望本文对您有所帮助!

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

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

相关文章

【机器学习】数据清洗之处理异常点

&#x1f388;个人主页&#xff1a;甜美的江 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进步…

php数组与字符串函数

php数组与字符串函数 1. php数组2. 字符串函数 1. php数组 在php中&#xff0c;有三种类型的数组&#xff1a; 数值数组 - 带有数字ID键的数组关联数组 - 带有指定的键的数组&#xff0c;每个键关联一个值多维数组 - 包含一个或多个数组的数组 2. 字符串函数 在PHP中&#xf…

vue三种路由守卫详解

在 Vue 中&#xff0c;可以通过路由守卫来实现路由鉴权。Vue 提供了三种路由守卫&#xff1a;全局前置守卫、全局解析守卫和组件内的守卫。 全局前置守卫 通过 router.beforeEach() 方法实现&#xff0c;可以在路由跳转之前进行权限判断。在这个守卫中&#xff0c;可以根据用…

leetcode(数组)128.最长连续序列(c++详细解释)DAY8

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给定一个未排序的整数数组 nums &#xff0c;找出数字连续的最长序列&#xff08;不要求序列元素在原数组中连续&#xff09;的长度。 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。 示例 示例 1&a…

GEE:梯度提升树(Gradient Boosting Tree)回归教程(样本点、特征添加、训练、精度、参数优化)

作者:CSDN @ _养乐多_ 对于分类问题,这个输出通常是一个类别标签 ,而对于回归问题,输出通常是一个连续的数值。回归可以应用于多种场景,包括预测土壤PH值、土壤有机碳、土壤水分、碳密度、生物量、气温、海冰厚度、不透水面积百分比、植被覆盖度等。 本文将介绍在Google…

Day 44 | 动态规划 完全背包、518. 零钱兑换 II 、 377. 组合总和 Ⅳ

完全背包 题目 文章讲解 视频讲解 完全背包和0-1背包的区别在于&#xff1a;物品是否可以重复使用 思路&#xff1a;对于完全背包问题&#xff0c;内层循环的遍历方式应该是从weight[i]开始一直遍历到V&#xff0c;而不是从V到weight[i]。这样可以确保每种物品可以被选择多次…

《Java 简易速速上手小册》第10章:Java 未来趋势和新特性(2024 最新版)

文章目录 10.1 Java 的新版本特性10.1.1 基础知识10.1.2 重点案例&#xff1a;使用 Java 14 的 Record 类简化数据模型10.1.3 拓展案例 1&#xff1a;利用 Java 11 的 HTTP Client 进行网络请求10.1.4 拓展案例 2&#xff1a;使用 Java 12 的 Switch 表达式优化代码 10.2 Java …

【UDS】搞懂时间参数

文章目录 背景时间参数的定义应用层相关会话层相关传输层相关网络层相关实际案例分析背景 TBD. 时间参数的定义 注意,这些时间参数都是超时阈值,需要理解为什么要有这些阈值,在哪一端判断这些阈值的,无需“死记硬背”它们的含义。 应用层相关 【P2 Client】 P2 Client 的…

Django学习全纪录:创建第一个Django项目,如何使用Django开发⼀个web应用

导言 在上一篇文章里,我们对Django的开发环境进行了学习以及搭建,在上一篇文章里,同时也为大家介绍了安装、验证、修改默认镜像源等知识。 在这一篇文章里,我们就正式开始我们的Django开发之旅,创建我们的第一个项目,做一些较为简单且必需的前置工作。 如何创建Django项目…

Promise与async await的作用及应用场景

在Web前端开发中&#xff0c;处理异步操作是非常常见的需求。为了解决这个问题&#xff0c;ES6引入了Promise和后续的async await。本文将介绍Promise和async await的作用&#xff0c;以及在实际开发中的应用场景。 一、Promise的作用及应用场景 Promise是一个表示异步操作最…

【教程】C++语言基础学习笔记(八)——函数

写在前面&#xff1a; 如果文章对你有帮助&#xff0c;记得点赞关注加收藏一波&#xff0c;利于以后需要的时候复习&#xff0c;多谢支持&#xff01; 【C语言基础学习】系列文章 第一章 《项目与程序结构》 第二章 《数据类型》 第三章 《运算符》 第四章 《流程控制》 第五章…

【JavaEE进阶】 图书管理系统开发日记——陆

文章目录 &#x1f38b;前言&#x1f343;删除图书&#x1f6a9;约定前后端交互接口&#x1f6a9;完善前端代码&#x1f6a9;接口测试 &#x1f38d;批量删除&#x1f6a9;约定前后端交互接口&#x1f6a9;实现后端服务器代码&#x1f388;控制层&#x1f388;业务层&#x1f3…

ICCV 2023 | 8篇论文看扩散模型diffusion用于图像检测任务:动作检测、目标检测、异常检测、deepfake检测...

1、动作检测 DiffTAD: Temporal Action Detection with Proposal Denoising Diffusion 基于扩散方法提出一种新的时序动作检测&#xff08;TAD&#xff09;算法&#xff0c;简称DiffTAD。以随机时序proposals作为输入&#xff0c;可以在未修剪的长视频中准确生成动作proposals。…

python-题库篇-列表、字典、元组、集合

文章目录 问题什么是Python中的列表&#xff08;List&#xff09;&#xff1f;它有哪些特点&#xff1f;什么是Python中的元组&#xff08;Tuple&#xff09;&#xff1f;它与列表有何区别&#xff1f;解释Python中的字典&#xff08;Dictionary&#xff09;Python中的集合&…

力扣刷题54-螺旋矩阵

给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;matrix [[1,2,3,…

《金融人工智能:用python实现ai量化交易》

融合了数学、python、深度学习以及金融知识&#xff0c;是本推荐的好书。请收藏本文&#xff0c;读后再给大学总结。

【python】网络爬虫与信息提取--Beautiful Soup库

Beautiful Soup网站&#xff1a;https://www.crummy.com/software/BeautifulSoup/ 作用&#xff1a;它能够对HTML.xml格式进行解析&#xff0c;并且提取其中的相关信息。它可以对我们提供的任何格式进行相关的爬取&#xff0c;并且可以进行树形解析。 使用原理&#xff1a;它能…

数模.SI模型SI的四种扩展

一&#xff1a;最简单的考虑方式 二考虑某种使得参数beta降低的因素 三&#xff1a;增加人口自然出生率和死亡率&#xff0c;但不考虑疾病的死亡率 四&#xff1a;不考虑人口自然出生率和死亡率&#xff0c;只考虑疾病的死亡率 五&#xff1a;同时考虑人口自然出生率和死亡率和…

【JavaEE】网络原理: UDP协议和TCP协议的相关内容

目录 1. 应用层 2. 传输层 2.1 端口号 2.2 UDP协议 2.3 TCP协议 1.确认应答 2.超时重传 3.连接管理 三次握手 四次挥手 状态转换 4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答 9.面向字节流 粘包问题 10.异常情况 网络通信中, 协议是一个非常重…

Java中锁的应用

文章目录 前言一、场景描述二、加锁1.synchronized2.ReentrantLock 三、扩展1.ThreadLocal 总结 前言 在多线程场景下&#xff0c;多个线程同时对共享变量进行操作是存在风险的&#xff0c;这时候就需要加锁来保证数据的正确性。 一、场景描述 我这里有5个无人机,准备卖到乌克…