第二十六节 SpringBoot开发自定义starter之配置自定义Starter提示信息

一、元数据格式

        提示文件编写在META-INF的spring-configuration-metadata.json文件下。元数据文件的大部分是在编译时通过处理所有用@ConfigurationProperties注释的项目自动生成的。 但是,对于极端情况或更高级的用例,可以手动编写部分元数据。

        配置元数据文件位于META-INF / spring-configuration-metadata.json下的jar内,它们使用简单的JSON格式,将项目归类为【groups】“组”或“【properties】属性”,并将其他值提示归类为【hints】“提示”

        每个“属性”都是用户使用给定值指定的配置项。 例如,可以在application.properties中指定server.port和server.address,如下所示:

server.port=9090
server.address=127.0.0.1

        【group】“组”是更高级别的项目,它们本身并不指定值,而是提供属性的上下文分组。 例如,server.port和server.address属性是服务器组的一部分。不需要每个“属性”都有一个“组”。 某些属性可能本身就存在。

        【hitnts】“提示”是用于帮助用户配置给定属性的其他信息。 例如,当开发人员配置spring.jpa.hibernate.ddl-auto属性时,工具可以使用提示为无提示提供一些自动完成帮助,验证,更新,创建和创建放置值。

group的属性

NameTypePurpose

 name

String

组的全名。 此属性是必需的。

type

String

组数据类型的类名。 例如,如果组基于@ConfigurationProperties注解的类,则该属性将包含该类的完全限定名称。 如果基于@Bean方法,则它将是该方法的返回类型。 如果类型未知,则可以省略该属性。

description

String

简单的描述,需要以 【.】点号结尾

sourceType

String

贡献此组的源的类名。 例如,如果组基于@ConfigurationProperties注解的@Bean方法,则此属性将包含包含该方法的@Configuration类的完全限定名称。 如果源类型未知,则可以省略该属性。

sourceMethod

String

贡献此组的方法的全名(包括括号和参数类型)(例如,@ ConfigurationProperties注释的@Bean方法的名称)。 如果源方法未知,则可以省略。

Properties的属性

name

String

属性的全名。名称以小写的句点分隔(例如server.address)。此属性是必需的。

type

String

属性的数据类型的完整签名(例如java.lang.String),还包含完整的通用类型(例如java.util.Map<java.util.String,acme.MyEnum>)。您可以使用此属性指导用户输入的值的类型。为了保持一致性,通过使用原始包装的对应对象来指定原始类型(例如,boolean变为java.lang.Boolean)。请注意,此类可能是一个复杂的类型,当String绑定值时会从转换为此类。如果类型未知,则可以省略。

description

String

可以显示给用户的组的简短描述。如果没有可用的描述,则可以省略。建议使用简短的描述,第一行提供简要的摘要。说明的最后一行应以句点(.)结尾。

sourceType

String

贡献此属性的源的类名。例如,如果属性来自带有注解的类@ConfigurationProperties,则此属性将包含该类的完全限定名称。如果源类型未知,则可以省略。

defaultValue

Object

默认值,如果未指定该属性,则使用该默认值。如果属性的类型是数组,则它可以是值的数组。如果默认值未知,则可以省略。

deprecation

Deprecation

指定是否不推荐使用该属性。如果不建议使用该字段,或者该信息未知,则可以将其省略。下表提供了有关该deprecation属性的更多详细信息。

hints提示属性

NameTypePurpose

name

String

该提示所引用的属性的全名。名称采用小写的句点分隔格式(例如spring.mvc.servlet.path)。如果该属性引用了Map(例如system.contexts),则提示将应用于Map的system.context.keys)或地图的system.context.values)。此属性是必需的。

values

ValueHint[]

ValueHint对象定义的有效值列表(如下表所述)。每个条目都定义该值,并且可以具有描述。

providers

ValueProvider[]

ValueProvider对象定义的提供者列表。每个条目定义提供者的名称及其参数(如果有)。

values每个hint元素的属性中包含的JSON对象可以包含下表中描述的属性:

NameTypePurpose

value

Object

用于上面的hints的values。

提示所引用元素的有效值。如果属性的类型是数组,则它也可以是值的数组。此属性是必需的。

description

String

可以显示给用户的值的简短描述。如果没有可用的描述,则可以省略。建议使用简短的描述,第一行提供简要的摘要。说明的最后一行应以句点(.)结尾。

providers每个hint元素的属性中包含的JSON对象可以包含下表中描述的属性 

名称类型目的

name

String

用于为提示所引用的元素提供附加内容帮助的提供者的名称。

parameters

JSON对象

提供程序支持的任何其他参数

二、开发提示

         SpringBoot会自动帮我们生成使用@ConfigurationProperties注解下的类的属性提示,在配置application.yml文件的时候会自动提示。生成的文件夹在Jar的META-INF/spring-configuration-metadata.json文件里面。

         如果我们想要自定义一些提示,并且限制用户输入某些属性的值,需要在开发starter的项目里面的META-INF文件夹下,创建additional-spring-configuration-metadata.json文件。

2.1  ANY

        providers  = any

        允许提供任何其他值。如果支持,则应基于属性类型进行常规值验证。

        如果具有值列表,并且任何其他值仍应视为有效,则通常使用此提供程序。

{
  "properties": [
    
    {
      "name": "system.user",
      "type": "java.lang.String",
      "defaultValue": "浙江大学",
      "description": "当前登录系统租户."
    }
  ],
  "hints": [
    {
      "name": "system.user",
      "values": [
        {
          "value": "浙江大学",
          "description": "用户浙大."
        },
        {
          "value": "北京大学",
          "description": "用户北大."
        },
        {
          "value": "深圳大学",
          "description": "用户深大."
        }
      ],
      "providers": [
        {
          "name": "any"
        }
      ]
    }
  ]
}

        导入starter后效果: 

        在properties里面的defaultValue是浙江大学,也就是说,推荐提示信息是“浙江大学”。如果不配置,在Controller了面用到了system.user属性,依然会报错。这个问题,我特地请教了公司的高级工程师,如何才能从yml中读取参数,如果读取不到,就使用默认的值呢?看下面的Java实例。

        先从配置文件里面读取system.user的值。如果用户没有配置,则取冒号后面的默认值。

        providers是any这种类型的配置,允许system.user指定任何值。

@RestController
public class HelloController ...

    @Value("${system.user:默认的大学}")
    private String user;

    @GetMapping(value = "/get")
    public String function() {
        return user;
    }
}

2.2  不配置

        若hitns里面不配置任何providers,则system.user的值必须取 hints.values里面的一个value。尝试使用非values里面的配置,则编译器标红。

{
  "properties": [
    
    {
      "name": "system.user",
      "type": "java.lang.String",
      "defaultValue": "浙江大学",
      "description": "当前登录系统租户."
    }
  ],
  "hints": [
    {
      "name": "system.user",
      "values": [
        {
          "value": "浙江大学",
          "description": "用户浙大."
        },
        {
          "value": "北京大学",
          "description": "用户北大."
        },
        {
          "value": "深圳大学",
          "description": "用户深大."
        }
      ]
    }
  ]
}

2.3  另外一种固定值的方式:使用枚举 

        如果希望调用者配置我们提供好的固定的一些值的时候,使用枚举也能实现。

package cn.tyzhou.config.hints;

public enum SexEnum {

    MAN("1", "男"),
    WOMEN("2", "女");

    private String code;
    private String name;

    //constract...
}
{
  "properties": [
    {
      "name": "user.sex",
      "description": "管理员性别."
    }
  ],
  "hints": [
    {
      "name": "user.sex",
      "providers": [
        {
          "name": "handle-as",
          "parameters": {
            "target": "cn.tyzhou.config.hints.SexEnum"
          }
        }
      ]
    }
  ]
}

2.4  类引用

        如果某个property希望使用的是一个类,并且这个类是指定的继承体系下的类,可以像下面一样配置。

        配置的是java.util.Collection,那么用户在配置这个property的时候,只能配置这个类及子类。

{
  "properties": [
    
    {
      "name": "system.class-name",
      "description": "类名."
    }
  ],
  "hints": [
   
    {
      "name": "system.class-name",
      "providers": [
        {
          "name": "class-reference",
          "parameters": {
            "target": "java.util.Collection"
          }
        }
      ]
    }
  ]
}

        根据配置,system.class-name的配置只能是集合框架Collection接口下面的实现类。

2.5  资源文件

        如果要让用户配置的是当前系统的资源文件,可以向下面一样配置。

{
  "properties": [
    
    {
      "name": "log-test.file",
      "description": "日志文件."
    }
  ],
  "hints": [
    {
      "name": "log-test.file",
      "providers": [
        {
          "name": "handle-as",
          "parameters": {
 
                 "target": "org.springframework.core.io.Resource"
           }
        }
      ]
    }
  ]
}

        更多配置,请参考SpringBoot官方文档:configuration-metadata-format

你看我都这么努力的分享知识给你了,鼓励一下又何妨O(∩_∩)O

你的打赏是对我最好的支持!

                    

posted @ 2022-07-17 12:13  小大宇  阅读(267)  评论(0编辑  收藏  举报