自定义spring boot starter 初尝试
自定义简单spring boot starter 步骤
从几篇博客中了解了如何自定义starter,大概分为以下几个步骤:
1 引入相关依赖;
2 生成属性配置类;
3 生成核心服务类;
4 生成自动化配置类;
5 注册配置/META-INF/spring.factories;
6 打包发布;
下面以一个简单的demo为例,一步一步说明自定义spring boot的starter的过程。
解决问题
使用Slf4j的MDC实现一个工程中的链路追踪。通过设置open的属性代表是否打开链路追踪,从而为每一个请求生成一个traceId。当然理想是比较丰满的,实际操作如果要实现上述功能,要配合AOP/Filter/Interceptor这类工具,具体参考 文章。本文只是做个demo。
引入相关依赖
Demo比较简单,所以需要的依赖也不多,如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency> </dependencies>
生成属性配置类
属性类一定要加@ConfigurationProperties注解,用于表示这个文件是一个属性类。
在注解@ConfigurationProperties后面可以添加prefix前缀,如果open属性要设置具体值,需要这样配置,lxl.mdc.open = true;
package com.demo.spring.starter.mdc; import org.springframework.boot.context.properties.ConfigurationProperties; /**
* 自定义starter的properties类
*
* @author lxl
* @since 2018/12/10
*/
@ConfigurationProperties(prefix = "lxl.mdc")
public class MdcDemoProperties {
private Boolean open = true; public Boolean getOpen() {
return open;
} public void setOpen(Boolean open) {
this.open = open;
} }
生成核心服务类
核心服务类的作用:根据properties中lxl.mdc.open的配置,控制是否生成sessionId,并将其put到MDC中。
package com.demo.spring.starter.mdc; import java.util.UUID; import org.slf4j.MDC; /**
* 自定义starter的核心服务类
*
* @author lxl
* @since 2018/12/10
*/
public class MdcDemoService {
private final String SESSION_ID = "SESSION_ID";
private MdcDemoProperties properties; public MdcDemoService() {
} public MdcDemoService(MdcDemoProperties properties) {
this.properties = properties;
} public String traceId() {
if (null != this.properties.getOpen() && false == this.properties.getOpen()) {
MDC.put(SESSION_ID, null);;
}else{
MDC.put(SESSION_ID, UUID.randomUUID().toString());
}
return MDC.get(SESSION_ID);
}
}
生成自动化配置类
@Configuration:标识此类为一个spring配置类
@EnableConfigurationProperties(MdcDemoProperties.class):启动配置文件,可以有多个,多个配置文件这样写:value={xxProperties1.class,xxProperteis2.class....}
@ConditionalOnClass
,当classpath
下发现该类的情况下进行自动配置。
更多注解参考 官方说明。
package com.demo.spring.starter.mdc; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; /***
* 自定义strter的配置类2
*
* @author lxl
* @since 2018/12/10
*/
@Configuration
@EnableConfigurationProperties(MdcDemoProperties.class)
@ConditionalOnClass(MdcDemoService.class) public class MdcDemoServiceAutoConfiguration {
@Autowired
private MdcDemoProperties properties; @Bean
@ConditionalOnMissingBean(MdcDemoService.class)
public MdcDemoService traceId() {
return new MdcDemoService(properties);
}
}
注册配置/META-INF/spring.factories
手动在resources文件下创建META-INF/spring.factories 文件,配置如下:org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.spring.starter.mdc.MdcDemoServiceAutoConfiguration
多个类通过,分隔即可。
打包发布
本地测试 可以通过 mvn install 打包命令打包成一个jar包,本地测试的话需要将mvn的settings文件的仓库改成本地地址,不然会出现找不到包的错误。
测试
1 新建一个spring boot 工程
参考 地址。
2 pom中引入mvn依赖
<dependency>
<groupId>com.alibaba.com.custom.starter</groupId>
<artifactId>mdc-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
3 mvn依赖查看
{
"groups": [
{
"name": "lxl.mdc",
"type": "com.demo.spring.starter.mdc.MdcDemoProperties",
"sourceType": "com.demo.spring.starter.mdc.MdcDemoProperties"
}
],
"properties": [
{
"name": "lxl.mdc.open",
"type": "java.lang.Boolean",
"sourceType": "com.demo.spring.starter.mdc.MdcDemoProperties"
}
],
"hints": []
}
4 配置application.properties
lxl.mdc.open = open
5 测试demo
@GetMapping(value = "/test")
public Result test(@RequestParam(name = "id") Long id) {
logger.info("==========test log requestId in controller==============");
System.out.println("applition.properties=" + env.getProperty("lxl.mdc.open"));
System.out.println("MDC.get('SESSION_ID')=" + service.traceId());
return dataplusAuthorityTenantService.testMDCInService(id);
}
6 测试输出
applition.properties=false
MDC.get('SESSION_ID')=null
applition.properties=true
MDC.get('SESSION_ID')=31f9f18d-893e-4dd7-b323-e9587968256b
p.p1 { margin: 0; font: 18px Monaco }
p.p1 { margin: 0; font: 18px Monaco }
span.s1 { color: rgba(57, 51, 255, 1) }
最新文章
- vs2015 HTTP Error 400. The request hostname is invalid.
- Windows安装和使用zookeeper
- 移动web开发之移动端真机测试
- 彻底弄明白之数据结构中的KMP算法
- 搞明白这八个问题,Linux系统就好学多了。
- HDU 3094 A tree game 树删边游戏
- OBS studio最新版配置鉴权推流
- 使用REST风格完成MVC前后端分离
- PHP 完整表单实例
- 五十、进程间通信——System V IPC 之共享内存
- 原生ajax可变参数post
- Functional Language
- 解决Kubelet Pod启动CreatePodSandbox或RunPodSandbox异常方法
- 249. Group Shifted Strings把迁移后相同的字符串集合起来
- Linux Platform驱动模型(三) _platform+cdev
- UI基础六:UI报弹窗确认
- Python爬虫框架Scrapy实例(三)数据存储到MongoDB
- centos6.5环境通过rpm包安装mysql5.5.51数据库
- 综合出现NSScanner: nil string argument libc++abi.dylib: terminat错误的解决方案
- C# 最全的系统帮助类
热门文章
- AR Engine运动跟踪能力,高精度实现沉浸式AR体验
- Apache Shiro反序列化漏洞(Shiro550)
- 写了个基于 MacOS + iTerm2 自动打开窗口执行命令的工具
- Codeforces Round #792 (Div. 1 + Div. 2) A-E
- Pod控制器类型
- python单元测试框架笔记
- CentOS7使用LVM缩减/home空间,扩大/空间
- jdk8 hashmap 链表resize 源码分析
- APISpace 周公解梦API接口 免费好用
- day11 Java反射机制