三分钟实战手写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
的写法