三分钟实战手写Spring Boot Starter
1 背景
在平时的开发中,开发的同学会把一些通用的方法,写成一个工具类,例如日期转换的,JSON转换的等等,方便业务后续调用,使代码更容易维护。
如果一些更常用的方法,例如鉴权的,加解密的等等,几乎每个项目都会使用到,这时候开发的同学就会从以前的项目中再抄过来,随着项目的增多,几乎每个项目都有一份一模一样的工具类。经过技术评审决定,将这些工具类打包成jar包,后续的新项目可以直接以jar包的形式引入,重用就会变得非常的好。
由于项目本身是基于Spring Boot进行开发,jar包以Spring Boot Starter的方式发布似乎是不错的选择。
2 介绍
Spring Boot Starter 和普通jar包的区别在于,Spring Boot Starter 更加灵活,提供了自动装配的机制,以及可供用户配置等。下面以 加解密作为例子,手写一个 Spring Boot Starter ,从实战到原理去了解它的工作过程。
3 创建项目
创建一个Spring Boot 的项目,项目命名为digest-spring-boot-starter
spring官方的包命名为:spring-boot-starter-xxx
第三方包命名为:xxx-spring-boot-starter
在pom.xml中引入依赖commons-codec(apache官方提供的加解密算法的工具包)
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
4 主体部分
加密逻辑书写,提供一个 Digest 接口,使用常用的 Md5和 Sha256摘要算法进行加密实现。
public interface Digest {
/**
* 摘要算法
* @param raw 字符串
* @return 加密后的字符串
*/
String digest(String raw);
}
public class Md5Digest implements Digest {
@Override
public String digest(String raw) {
System.out.println("使用MD5算法生成摘要");
return DigestUtils.md5Hex(raw);
}
}
public class Sha256Digest implements Digest {
@Override
public String digest(String raw) {
System.out.println("使用SHA256算法生成摘要");
return DigestUtils.sha256Hex(raw);
}
}
如果需要用户来指定使用哪种加密算法,需要在application.properties中添加一项配置:
digest.type=sha
创建一个配置类,拿到用户配置的type:
@Configuration
@EnableConfigurationProperties
@ConfigurationProperties(prefix = "digest")
public class Config {
private String type;
/**
* <bean id="md5Digest" class="com.xiaofengstu.digest.impl.Md5Digest"/>
* @return Digest
*/
@Bean
@ConditionalOnProperty(prefix = "digest", name = "type", havingValue = "md5")
public Digest md5Digest() {
return new Md5Digest();
}
@Bean
@ConditionalOnProperty(prefix = "digest", name = "type", havingValue = "sha")
public Digest sha256Digest() {
return new Sha256Digest();
}
}
日常开发中,比较常用的几个注解为:
@ConditionalOnBean:当容器中存在指定Bean的条件下
@ConditionalOnClass:当类路径匣有指定类的条件下
@ConditionalOnProperty:指定的属性是否有指定的值
5 配置自动装配
在 resources 目录下,创建一个文件夹名为 META-INF,创建一个文件名为spring.factories
这一步是固定写法
由于我们自己开发的starter是没有启动类的,所以需要告诉引用 starter 的项目,需要去加载哪些类。
在spring.factories中填写:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xiaofengstu.digest.conf.Config
注释掉pom.xml中关于spring-boot-maven-plugin的部分,以至于后续执行 mvn package 操作得到是一个标准的jar包。
再执行mvn install 将 starter打包到本地仓库中。
6 使用starter
在需要的项目中引入刚刚打包好的starter:
<dependency>
<groupId>com.xiaofengstu</groupId>
<artifactId>digest-spring-boot-starter</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
在代码中直接注入 Digest 即可:
@Resource
private Digest digest;
总结
spring boot 2.7+ 的版本,
spring.factorys写法稍有改动:
文件内容,一行就是一个装配类:

如果没看明白的,可以参考一下
mybatis-plus-spring-boot-starter的写法
三分钟实战手写Spring Boot Starter的更多相关文章
- 自己写spring boot starter
自己写spring boot starter 学习了:<spring boot实战>汪云飞著 6.5.4节 pom.xml <project xmlns="http://m ...
- 手把手教你手写一个最简单的 Spring Boot Starter
欢迎关注微信公众号:「Java之言」技术文章持续更新,请持续关注...... 第一时间学习最新技术文章 领取最新技术学习资料视频 最新互联网资讯和面试经验 何为 Starter ? 想必大家都使用过 ...
- Spring Boot Starter自定义实现三步曲
实现自定义的spring boot starter,只需要三步: 1.一个Bean 2.一个自动配置类 3.一个META-INF/spring.factories配置文件 下面用代码演示这三步. 项目 ...
- 年轻人的第一个自定义 Spring Boot Starter!
陆陆续续,零零散散,栈长已经写了几十篇 Spring Boot 系列文章了,其中有介绍到 Spring Boot Starters 启动器,使用的.介绍的都是第三方的 Starters ,那如何开发一 ...
- 从零开始开发一个Spring Boot Starter
一.Spring Boot Starter简介 Starter是Spring Boot中的一个非常重要的概念,Starter相当于模块,它能将模块所需的依赖整合起来并对模块内的Bean根据环境( 条件 ...
- 手写Spring MVC
闲及无聊 又打开了CSDN开始看一看有什么先进的可以学习的相关帖子,这时看到了一位大神写的简历装X必备,手写Spring MVC. 我想这个东西还是有一点意思的 就拜读了一下大佬的博客 通读了一遍相关 ...
- AI应用开发实战 - 手写识别应用入门
AI应用开发实战 - 手写识别应用入门 手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等.但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手.本文从简单的MNIST训练出 ...
- 一个老程序员是如何手写Spring MVC的
人见人爱的Spring已然不仅仅只是一个框架了.如今,Spring已然成为了一个生态.但深入了解Spring的却寥寥无几.这里,我带大家一起来看看,我是如何手写Spring的.我将结合对Spring十 ...
- Spring Boot (一): Spring Boot starter自定义
前些日子在公司接触了spring boot和spring cloud,有感于其大大简化了spring的配置过程,十分方便使用者快速构建项目,而且拥有丰富的starter供开发者使用.但是由于其自动化配 ...
- 我是这样手写 Spring 的(麻雀虽小五脏俱全)
人见人爱的 Spring 已然不仅仅只是一个框架了.如今,Spring 已然成为了一个生态.但深入了解 Spring 的却寥寥无几.这里,我带大家一起来看看,我是如何手写 Spring 的.我将结合对 ...
随机推荐
- JUC-学习笔记
传统的多线程开发方式 implements Runnable public class oldThreadDev implements Runnable { @Override public void ...
- laravel框架 forelse和foreach
1. @forelse($data as $v) 循环数据内容..... @empty 数据为空提示... @endforelse 2. @foreach($data as $v) 循环数据内容... ...
- NET 6 实现滑动验证码(三)、接口
题外话,有网友说,这玩意根本很容易破解,确实是这样.但验证码这东西,就跟锁子很类似,防君子不防小人.验证码的发明其实是社会文明的退步.因为它阻碍了真正的使用者,却无法阻挡别有用心的人.但又有什么办法呢 ...
- 【Shell案例】【小数点scale&bc】14、求平均值
描述写一个bash脚本以实现一个需求,求输入的一个的数组的平均值 第1行为输入的数组长度N第2~N行为数组的元素,如以下为:数组长度为4,数组元素为1 2 9 8示例:41298 那么平均值为:5.0 ...
- python 集合常用操作
集合的特性 无序.不重复.可迭代 常用api 创建一个集合 需要显式地使用set()方法来声明,如果使用字面量{}来声明解析器会认为这是一个字典. add() 往集合中添加一个元素 demo = se ...
- Kali Win-KeX Win
内容: 概述 用法 开始 启动根会话 会话管理 声音支持 多屏支持 停止 概述 窗口模式下的 Win-KeX 将在单独的窗口中运行 Kali Linux 桌面会话. 窗口模式有助于在视觉上将 Wind ...
- [深度学习]DEEP LEARNING(深度学习)学习笔记整理
转载于博客http://blog.csdn.net/zouxy09 一.概述 Artificial Intelligence,也就是人工智能,就像长生不老和星际漫游一样,是人类最美好的梦想之中的一个. ...
- kafka详解(01) - 概述
kafka详解(01) - 概述 定义:Kafka是一个分布式的基于发布/订阅模式的消息队列(Message Queue),主要应用于大数据实时处理领域. 消息队列 MQ传统应用场景之异步处理 使用消 ...
- Java正则表达式全局匹配
今天想用Java的正则在字符串中匹配特定内容,但是当我代码写好运行后却发现正则表达式并没有起作用 试了很多方法,也去Js里试了正则表达式可以走通,就是Java不行 很纳闷 (:′⌒`) Java里正则 ...
- Java8常见函数式接口总结
函数式接口 函数式接口:有且仅有一个抽象方法的接口. 使用@FunctionalInterface注解来标记.如果接口不是函数式接口就会编译出错 满足条件的接口即使不加上注解,那也是函数式接口 函数式 ...