自定义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

   

posted @ 2018-12-11 16:38  梨小落是个小疯子  阅读(328)  评论(0编辑  收藏  举报