持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
如何自定义 starter
SpringBoot 的核心就是自动配置, 而支持自动配置的是一个个 starter 项目. 除了官方已有的starter, 用户也可以根据规则自定义自己的 starter 项目.
实现一个 starter 有四个要素:
starter 命名,需要遵守一定规范.自动配置类, 用来初始化相关的 bean.- 指明自动配置类的配置文件
spring.factories. 自定义属性实体类, 声明 starter 的应用配置属性.
starter 的命名规范
starter 的名字,也就是在 pom 中引用的 artifactId. 命名是有规则的, 官方规定:
- 官方的 starter 的命名格式为
spring-boot-starter-{name}, 如:spring-boot-starter-actuator. - 非官方的 starter 的命名格式为
{name}-spring-boot-starter
创建maven项目, 并填写 starter 的名字:
<groupId>it.com</groupId>
<artifactId>msg-spring-boot-starter</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
自定义 starter
短信发送是个很常见的功能,并且本身独立,使用的地方也比较多,完全可以独立出去,作为 starter 使用。
这个自定义的 starter 的源码地址 : msg-spring-boot-starter
最终结构如下:
① 引入 SpringBoot 自动化配置依赖 :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.3.RELEASE</version>
</dependency>
除此之外, 根据需要, 可以引入其他依赖.
② 定义 Service 服务类
定义 Service 服务类, 有两个作用, 一个为引入的项目本身的功能服务, 另外一个用来 Springboot 自动配置时的判断依据. 该服务类和 xxxTemplate 类似的功能.
这里定义一个 MsgService 的类.
@Data
public class MsgService {
// 访问发送短信的url地址
private String url;
// 短信服务商提供的请求keyId
private String accessKeyId;
// 短信服务商提供的KeySecret
private String accessKeySecret;
public MsgService(String url, String accessKeyId, String accessKeySecret) {
this.url = url;
this.accessKeyId = accessKeyId;
this.accessKeySecret = accessKeySecret;
}
public int sendMsg(String msg) {
// 调用http服务并发送消息, 返回结果
return HttpClientUtils.sendMsg(url, accessKeyId, accessKeySecret, msg);
}
}
其中 MsgService 用到了一个自定义工具类 HttpClientUtils. 在 HttpClientUtils 中只是简单打印了请求的参数信息. 并没有实际发出请求. HttpClientUtils
③ 定义配置类
定义 MsgProperties 配置类, 用于封装 application.properties 或 application.yml 中的基础配置. 这里关于短信发送的配置前缀统一采用 msg. MsgProperties
通过 @ConfigurationProperties 注解来进行对应的属性的装配.
@Data
@ConfigurationProperties(prefix = "msg")
public class MsgProperties {
// 访问发送短信的url地址
private String url;
// 短信服务商提供的请求keyId
private String accessKeyId;
// 短信服务商提供的KeySecret
private String accessKeySecret;
}
④ 创建自动化配置类
自动配置类就是一个普通的 Java 类, 通过不同的注解来对其赋予不同的功能. 其中最核心的当然是 @Configuration 注解. MsgAutoConfiguration
@Configuration
@ConditionalOnClass(MsgService.class)
@EnableConfigurationProperties(MsgProperties.class)
public class MsgAutoConfiguration {
//注入属性配置类
@Resource
private MsgProperties msgProperties;
@Bean
@ConditionalOnMissingBean(MsgService.class)
@ConditionalOnProperty(prefix = "msg", value = "enabled", havingValue = "true")
public MsgService msgService() {
MsgService msgService = new MsgService(msgProperties.getUrl(),
msgProperties.getAccessKeyId(),
msgProperties.getAccessKeySecret());
// 如果提供了其他set方法, 在此也可以调用对应方法对其进行相应的设置或初始化.
System.out.println(msgService);
return msgService;
}
}
MsgAutoConfiguration 类上的注解 :
-
注解
@Configuration用来声明该类为一个配置类. -
注解
@ConditionalOnClass说明只有当 MsgService 类存在于 classpath 中时才会进行相应的实例化 -
注解
@EnableConfigurationProperties会将 application.properties 中对应的属性配置设置到 MsgProperties 对象中.
msgService 方法上的注解 :
-
注解
@Bean表明该方法实例化的对象会被加载到容器当中 -
注解
@ConditionalOnMissingBean表示当容器中不存在 MsgService 的对象时, 再进行实例化. -
注解
@ConditionalOnProperty表示当配置文件中 msg.enabled=true 时才进行相应的实例化.
⑤ 添加 spring.factories
在 resource/META-INF 目录下创建名称为 spring.factories 的文件, 对其进行注册.
在 spring.factories 配置文件中注册 MsgAutoConfiguration 类. 如果有多个自动配置类, 用逗号分隔换行即可.
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
it.com.config.MsgAutoConfiguration
⑥ 至此, 一个基于 Spring Boot 的自动配置 starter 便完成了.
打包安装
starter 编写完成之后, clean -> package -> install 安装到本地 maven 仓库. 方便其他项目中引用使用.
在其他项目中使用
在其他项目中, 引入该 自定义 starter 依赖.
<dependency>
<groupId>it.com</groupId>
<artifactId>msg-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
并配置需要的参数:
msg:
enabled: true
url: 127.0.0.1
accessKeyId: 10001
accessKeySecret: afelwjfwfwef
测试使用 :
@RestController
public class HelloWorldController {
@Resource
private MsgService msgService; // 自定义的 starter 中的 service
@RequestMapping("/sendMsg")
public String sendMsg(){
msgService.sendMsg("测试消息");
return "ok";
}
}
自定义 Starter 之 oss
自定义一个 oss-spring-boot-starter 文件上传的 Starter. oss-spring-boot-starter
- 注解
@ConditionalOnWebApplication表示当 Spring 为 web 服务时, 才使注解的类生效.
使用 :
oss:
config:
enable: true
endpoint:
access-key-id:
access-key-secret:
bucket-name:
dir: blog/
其他优秀的 Starter
-
kongchong/exception-notice-spring-boot-starter: 一个针对异常信息通知的springboot starter
-
yinjihuan/elastic-job-spring-boot-starter: Elastic-Job Spring Boot 自动集成,只需要一个注解即可发布Job
-
wj596/jsets-shiro-spring-boot-starter: SpringBoot Starter for Shiro (springboot shiro 权限管理插件)
【源码】Starter 的工作流程
大概流程:
-
Spring Boot 在启动时扫描项目所依赖的 JAR 包, 寻找包含 spring.factories 文件的 JAR 包.
-
根据 spring.factories 配置加载 AutoConfiguration 类.
-
根据 @Conditional 注解的条件, 进行自动配置并将 Bean 注入 Spring 容器.
具体细节:
todo