当前位置: 首页 > news >正文

手写SpringBoot的starter

自定义SpringBoot的starter

引言

starter命名格式:

  • 官方的 starter 的命名格式为 spring-boot-starter-{xxxx} 比如spring-boot-starter-activemq
    第三方我们自己的命名格式为 {xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter。
    如果我们忽略这种约定,是不是会显得我们写的东西不够“专业“。

实战

完整项目结构:
在这里插入图片描述

①导入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.18</version><scope>provided</scope>
</dependency>

②编写配置文件类(SmsProperties)

@ConfigurationProperties(prefix = "sms")
@Data
public class SmsProperties {private SmsMessage aliyun = new SmsMessage();private SmsMessage tencent = new SmsMessage();@Datapublic static class SmsMessage{/*** username 用户名*/private String userName;/*** 密码*/private String passWord;/*** 秘钥*/private String sign;/****/private String url;@Overridepublic String toString() {return "SmsMessage{" +"userName='" + userName + '\'' +", passWord='" + passWord + '\'' +", sign='" + sign + '\'' +", url='" + url + '\'' +'}';}}
}

@ConfigurationProperties注解上配置的prefix 属性,主要用来区别各个组件的参数。

  • 这里有个小知识点需要注意下当我们在配置文件输入sms我们的idea会提示这个sms有哪些属性可以配置,以及每个属性的注释都有标记,建议的话注释还是写英文,这样会显得你比较专业。
    如果想要把此处字段上的注释展示出来,则需要导入
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-configuration-processor</artifactId><optional>true</optional>
</dependency>

效果:
在这里插入图片描述

③编写自动配置类

@EnableConfigurationProperties(value = SmsProperties.class)
@Configuration
public class SmsAutoConfiguration  {/***  阿里云发送短信的实现类* @param smsProperties* @return*/@Beanpublic AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){return new AliyunSmsSenderImpl(smsProperties.getAliyun());}/*** 腾讯云发送短信的实现类* @param smsProperties* @return*/@Beanpublic TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){return new TencentSmsSenderImpl(smsProperties.getTencent());}
}

④接口及实现类

接口:

public interface SmsSenderService {boolean send(String msg);
}

实现类:

public class TencentSmsSenderImpl implements SmsSenderService{private SmsProperties.SmsMessage smsMessage;public TencentSmsSenderImpl(SmsProperties.SmsMessage smsProperties) {this.smsMessage = smsProperties;}@Overridepublic boolean send(String message) {System.out.println(smsMessage.toString()+"开始发送短信==》短信内容:"+message);return true;}
}
public class AliyunSmsSenderImpl implements SmsSenderService {private SmsProperties.SmsMessage smsMessage;public AliyunSmsSenderImpl(SmsProperties.SmsMessage smsProperties) {this.smsMessage = smsProperties;}@Overridepublic boolean send(String message) {System.out.println(smsMessage.toString()+"开始发送短信==》短信内容:"+message);return true;}
}

⑤让starter生效(应用集成)

starter集成应用有两种方式:

  1. 被动生效

通过SpringBoot的SPI机制

  • resources目录下新建一个META-INF目录
  • 在META-INF目录下创建spring.factories
  • spring.factories写入:

在这里插入图片描述

注意两行都是顶格写

  1. 主动生效(注解)

在starter组件集成到我们的Spring Boot应用时需要主动声明启用该starter才生效

  • 通过自定义一个@Enable注解然后在把自动配置类通过Import注解引入进来。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}

使用的时候需要在启动类上面开启这个注解。
在这里插入图片描述

⑥mvn install打包到本地仓库

记得需要打包到本地仓库(别忘记将settings中的maven配置修改为本地的maven)

BUG:如果我们引入了自定义的starter之后,仍然找不到,则需要在自定义starter项目中添加插件(因为多了BOOT-INF)

<!--找不到自定义starter-->
<plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><skip>true</skip></configuration>
</plugin>

⑦使用

  1. 新建项目,引入我们的starter依赖
<!--自定义starter-->
<dependency><groupId>com.zi</groupId><artifactId>sms-spring-boot-starter</artifactId><version>1.0.0</version>
</dependency>
  1. 编写配置文件
server:port: 8080
# 自定义starter中的配置
sms:aliyun:user-name: ziyipass-word: 123456url: https://aliyun.com/send
  1. 测试类中的启动类
@SpringBootApplication
//@EnableSms
public class StarterDemoApplication {@Autowiredpublic static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(StarterDemoApplication.class, args);AliyunSmsSenderImpl aliyunSmsSender = applicationContext.getBean(AliyunSmsSenderImpl.class);aliyunSmsSender.send("用阿里云发送短信");}}
  1. 启动Application,查看结果
    在这里插入图片描述

参考:
https://developer.aliyun.com/article/893073

相关文章:

手写SpringBoot的starter

自定义SpringBoot的starter 引言 starter命名格式&#xff1a; 官方的 starter 的命名格式为 spring-boot-starter-{xxxx} 比如spring-boot-starter-activemq 第三方我们自己的命名格式为 {xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter。 如果我们忽略这种约定…...

pytorch1.2.0+python3.6

一、说明 pytorch1.2.0python3.6CUDA10.0cudnn7.4.1.5 二、步骤 在conda中创建一个新的虚拟环境 查看一下自己的所有环境 激活虚拟环境 conda activate torch1.2.0 关于cuda和cudnn 1、查看自己电脑系统是10.2版本 http://链接&#xff1a;https://pan.baidu.com/s/1v5cN6…...

WindowsPowerShell 停止、启动、暂停和重启服务、卸载服务

PowerShell 停止、启动、暂停和重启服务、卸载服务 PowerShell 停止、启动、暂停和重启服务 官文 powershell卸载服务 官文 目录PowerShell 停止、启动、暂停和重启服务、卸载服务停止、启动、暂停和重启停止服务启动服务暂停服务重启服务卸载移除服务停止、启动、暂停、重启…...

数据库专题

请简洁描述 MySQL 中 InnoDB 支持的四种事务隔离级别名称&#xff0c;以及逐级之间的区别&#xff1f; 默认隔离级别 mysql repeatable-read oracle read-committed 脏读&#xff1a;不可重复读&#xff1a;幻读&#xff1a; CHAR 和 VARCHAR 的区别&#xff1f;…...

浅谈MySQL索引

目录 1.索引的定义 2.索引的原理 3.Hash索引与B Tree索引 4.索引的分类 5.建立索引的注意事项 1.索引的定义 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。 索…...

安装包UI美化之路-通过nsNiuniuSkin来做Electron程序的打包、发布与升级

nsNiuniuSkin从发布之初&#xff0c;因其简单、简洁、高效&#xff0c;受到了非常多公司的青睐&#xff0c;现在已经越来越多的公司采用我们的这套解决方案来制作安装包了&#xff01; 从一个安装包UI插件&#xff0c;逐步演化成一套集美观、安全、简洁、自动化为一体的完整的…...

飞鹅打印机怎么样?飞鹅打印机好用吗?飞鹅打印机怎么知道订单是否漏单?

外卖打印机怎么选?飞鹅打印机好用吗&#xff1f;飞鹅智能云打印机产品专注于云打印的解决方案和技术服务提供。2019 年飞鹅已经成为国内先进的云打印服务提供商&#xff0c;主要是服务美团、饿了么客户&#xff0c;产品主要优势&#xff1a;自动接单、自动打印&#xff0c;无需…...

网络协议(八):传输层-TCP(三次握手、四次挥手原理)

网络协议系列文章 网络协议(一)&#xff1a;基本概念、计算机之间的连接方式 网络协议(二)&#xff1a;MAC地址、IP地址、子网掩码、子网和超网 网络协议(三)&#xff1a;路由器原理及数据包传输过程 网络协议(四)&#xff1a;网络分类、ISP、上网方式、公网私网、NAT 网络…...

最新OpenMVG编译安装与逐命令运行增量式和全局式SfM教程

openmvg是一个轻便的可以逐步运行的SfM开源库&#xff0c;它同时实现了增量式和全局式两种算法。 说明文档地址&#xff1a;https://openmvg.readthedocs.io/en/latest/ github主页地址&#xff1a;https://github.com/openMVG/openMVG 1 编译安装 openmvg的安装比较简单&…...

数据结构与算法系列之插入排序

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注再收藏 &#x1f31e; 什么是插入排序 有一个已经有序的数据序列&#xff0c;要求在这个已经排好的数…...

Text to image论文精读ALR-GAN:文本到图像合成的自适应布局优化

ALR-GAN是北京工业大学学者提出的一种自适应布局优化生成对抗网络&#xff0c;其可以在没有任何辅助信息的情况下自适应地优化合成图像的布局。 文章发表于2023年&#xff0c;IEEE Transactions on Multimedia&#xff08;TMM&#xff09;期刊&#xff08;CCF B&#xff0c;JCR…...

windows版 redis在同一局域网下互联

项目场景&#xff1a; 同一局域网下各个主机互相连接同一个redis 问题描述 无法连接 原因分析&#xff1a; 没有放行对方的地址 解决方案&#xff1a; 修改配置文件 最重要的一步如下 然后把 redis.windows.conf的文件也照上面的修改一下保持一致 然后安装一下redis服务这…...

Near-Optimal Bayesian Online Assortment of Reusable Resources

摘要 受租赁服务在电子商务中的应用的激励&#xff0c;我们考虑为不同类型的到达消费者提供可重复使用资源的在线分类的收入最大化。我们针对贝叶斯环境中的最优在线策略设计了具有竞争力的在线算法&#xff0c;其中类型随时间独立于已知的异构分布绘制。在初始库存最小值cmin…...

数据库复习2

一. 简答题&#xff08;共1题&#xff0c;100分&#xff09; 1. (简答题) 存在数据库test&#xff0c;数据库中有如下表&#xff1a; 1.学生表 Student(Sno,Sname,Sage,Ssex) --Sno 学号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 主键Sno 2.教师表 Teacher(Tno,Tname) --T…...

公众号运营之竞品分析,教你拆解公众号

知己知彼&#xff0c;百战不殆&#xff0c;公众号运营亦是如此。 当运营者只关注自己账号的时候&#xff0c;很容易陷入某个误区中出不来。这个时候就要拓宽我们的视野&#xff0c;多去看看“外面的世界”&#xff0c;不要只局限于自己的一片小天地中。 看看同领域优秀公众号…...

python常见问题详解

Python python 没有多态&#xff0c;而是鸭子类型 多继承&#xff0c;没有接口&#xff0c;可通过语法糖实现接口的作用 lambda中只能有一句 "/"表示之前的参数是必须是位置参数&#xff0c;”**“表示是后面的必须是关键字参数 Python多进程 Python 多线程是伪多线…...

MyBatis-常用SQL操作

一、动态SQL 1.概述】 1.1动态SQL&#xff1a; 是 MyBatis 的强大特性之一&#xff0c;解决拼接动态SQL时候的难题&#xff0c;提高开发效 1.2分类&#xff1a; if choose(when,otherwise) trim(where,set) foreach 2.if 2.1 做 where 语句后面条件查询的,if 语句是可以…...

DSPE-PEG-TCO;磷脂-聚乙二醇-反式环辛烯科研用化学试剂简介

中文名称 磷脂-聚乙二醇-反式环辛烯 英文名称 DSPE-PEG-TCO 外观&#xff1a;粉末或半固体&#xff0c;取决于分子量。 溶剂&#xff1a;溶于大部分有机溶剂&#xff0c;如&#xff1a;DCM、DMF、DMSO、THF等等。在水中有很好的溶解性 稳定性&#xff1a;冷藏保存&#xff…...

华为OD机试真题Java实现【最小施肥机能效】真题+解题思路+代码(20222023)

最小施肥机能效 某农场主管理了一大片果园,fields[i]表示不同果林的面积,单位:( m 2 m^2 m2),现在要为所有的果林施肥且必须在 n 天之内完成,否则影响收成。 小布是果林的工作人员,他每次选择一片果林进行施肥,且一片果林施肥完后当天不再进行施肥作业。 假设施肥机的…...

【问题记录】【排查问题的方法总结】vue3中数据失去响应式?为什么数据变了,视图只更新了一次就不再更新了?

一、问题概述&#xff1a; 持续请求的数据变动之后&#xff0c;控制台输出绑定的响应式变量 mapObj 的确变了&#xff0c;但是视图上只更新了一次&#xff0c;后续就不再更新了。 二、排查过程&#xff1a; PC上用定时器setInterval模拟数据(全是小于0的数据)更新&#xff0…...

【kafka】Golang实现分布式Masscan任务调度系统

要求&#xff1a; 输出两个程序&#xff0c;一个命令行程序&#xff08;命令行参数用flag&#xff09;和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽&#xff0c;然后将消息推送到kafka里面。 服务端程序&#xff1a; 从kafka消费者接收…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Keil 中设置 STM32 Flash 和 RAM 地址详解

文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...