自定义简单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) }

自定义spring boot starter 初尝试的更多相关文章

  1. 年轻人的第一个自定义 Spring Boot Starter!

    陆陆续续,零零散散,栈长已经写了几十篇 Spring Boot 系列文章了,其中有介绍到 Spring Boot Starters 启动器,使用的.介绍的都是第三方的 Starters ,那如何开发一 ...

  2. 最详细的自定义Spring Boot Starter开发教程

    1. 前言 随着Spring的日渐臃肿,为了简化配置.开箱即用.快速集成,Spring Boot 横空出世. 目前已经成为 Java 目前最火热的框架了.平常我们用Spring Boot开发web应用 ...

  3. Spring Boot(3)---自定义spring boot starter 问题

    1. "Failed to process import candidates for configuration class [com.simple.....]": 主要原因: ...

  4. Sping Boot入门到实战之实战篇(一):实现自定义Spring Boot Starter——阿里云消息队列服务Starter

    在 Sping Boot入门到实战之入门篇(四):Spring Boot自动化配置 这篇中,我们知道Spring Boot自动化配置的实现,主要由如下几部分完成: @EnableAutoConfigu ...

  5. 自定义 Spring Boot Starter

    关于Starter Spring Boot秉承"约定大于配置"的开发方式,使得我们基于Spring Boot开发项目的效率变得十分高.相信使用过Spring Boot的小伙伴都会发 ...

  6. spring boot docker 初尝试

    Docker服务中进程间通信通过/var/run/docker.sock实现,默认服务不提供监听端口,因此使用docker remote api 需要手动绑定端口. 在centos7.2下,可以进行这 ...

  7. Spring Boot Starter 开发指南

    Spring Boot Starter是什么? 依赖管理是任何复杂项目的关键部分.以手动的方式来实现依赖管理不太现实,你得花更多时间,同时你在项目的其他重要方面能付出的时间就会变得越少. Spring ...

  8. Spring Boot (一): Spring Boot starter自定义

    前些日子在公司接触了spring boot和spring cloud,有感于其大大简化了spring的配置过程,十分方便使用者快速构建项目,而且拥有丰富的starter供开发者使用.但是由于其自动化配 ...

  9. 自定义的Spring Boot starter如何设置自动配置注解

    本文首发于个人网站: 在Spring Boot实战之定制自己的starter一文最后提到,触发Spring Boot的配置过程有两种方法: spring.factories:由Spring Boot触 ...

随机推荐

  1. 利用shell脚本自动化备份数据库与手动备份还原数据库操作

    1.在linux操作系统上手动备份数据库 mysqldump -h 服务器IP地址 -u root -p数据库密码 --databases 所要备份的数据库名称 > /路径/数据库.sql(自定 ...

  2. GDKOI 2021 Day2 TG 总结

    又是爆炸的一天,炸多了本蒟蒻已经习以为常 但今天比昨天整整高了 40 分!!!!却还是没有 100 今天本蒟蒻本想模仿奆佬的打字速度,结果思路混乱让我无法开始 T1 不是吧怎么是期望 dp ,期望值怎 ...

  3. Mysql中文存储、显示及不区分大小写控制

    刚开始使用mysql,以为安装了完了就可以使用了,结果是我太天真了.mysql5.7版本,默认严格区分大小写,并且不支持中文存储. 严格区分大小写,即A表和a表示两个不同的表 实例 修改 在/etc/ ...

  4. Camunda定时器事件示例Demo(Timer Events)

    ​Camunda定时器事件(Timer Events)是由定义的计时器触发的事件.它们可以用作启动事件.中间事件或边界事件.边界事件可以中断,也可以不中断. Camunda定时器事件包括:Timer ...

  5. 3.对互斥事件和条件概率的相互理解《zobol的考研概率论教程》

    tag:这篇文章没太多思考的地方,就是做个过渡 1.从条件概率来定义互斥和对立事件 2.互斥事件是独立事件吗? 3.每个样本点都可以看作是互斥事件,来重新看待条件概率 一.从条件概率来定义互斥和对立事 ...

  6. 基于.NetCore开发博客项目 StarBlog - (12) Razor页面动态编译

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  7. zabbix监控钉钉报警

    1. bash脚本 #!/bin/bash to=$1 subject=$2 text=$3 #此处的 xxxxx 就是刚刚复制存留的 api 接口地址. curl -i -X POST \ 'htt ...

  8. ArrayList分析1-循环、扩容、版本

    ArrayList分析1-循环.扩容.版本 转载请注明出处 https://www.cnblogs.com/funnyzpc/p/16407733.html 前段时间抽空看了下ArrayList的源码 ...

  9. ReentrantLock 公平锁源码 第2篇

    Reentrant 2 前两篇写完了后我自己研究了下,还有有很多疑惑和问题,这篇就继续以自问自答的方式写 如果没看过第1篇的可以先看看那个https://www.cnblogs.com/sunanka ...

  10. 网络通信协议分类和IP地址

    网络通信协议分类 通信的协议还是比较复杂的,java.net 包中包含的类和接口,它们提供低层次的通信细节.我们可以直接使用这些类和接口,来专注于网络程序开发,而不用考虑通信的细节 java.net ...