SpringBoot 配置提示功能-LMLPHP

目的

配置自动提示的辅助功能可以让配置写起来更快,准确率大大提高。

版本

参考 SpringBoot 2.2.0.RELEASE 文档

文件

jar包中的 META-INF/spring-configuration-metadata.json (自动生成)或 META-INF/additional-spring-configuration-metadata.json (手动添加)

实战

<!-- 引入相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Configuration
@ConfigurationProperties(prefix = "file.upload")
public class FileUploadConfig {
/** Maximum number of bytes per file */
private String maxSize = "1024M"; /** 不允许的文件后缀 */
private String rejectSuffix;
//注意:使用的时候必须要有getter/setter,否则不会自动生成该属性对应的提示
//此处因为篇幅原因省略 getter/setter
}
@Configuration
@ConfigurationProperties("map.test")
public class MapTestConfig {
/** 测试Map类型数据的提示 */
private Map<String, Object> data;
//注意:使用的时候必须要有getter/setter,否则不会自动生成该属性对应的提示
//此处因为篇幅原因省略 getter/setter
}

中文注释会乱码,以上故意用中文注释的地方,会在下面文件中指定对应的描述,看是否会覆盖。

additional-spring-configuration-metadata.json

{
"properties": [
{
"name": "file.upload.reject-suffix",
"type": "java.lang.String",
"defaultValue": "exe,jar",
"description": "The file suffix is not allowed.",
"sourceType": "com.lw.metadata.config.FileUploadConfig"
},
{
"name": "map.test.data",
"type": "java.util.Map",
"description": "Tips for testing Map type data.",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"hints": [
{
"name": "map.test.data.keys",
"values": [
{
"value": "name",
"description": "The name of the person."
},
{
"value": "sex",
"description": "The sex of the person."
}
]
}
]
}

maven compile 之后,生成的 additional-spring-configuration-metadata.json 与源码中的一样,生成的 spring-configuration-metadata.json 如下:

{
"groups": [
{
"name": "file.upload",
"type": "com.lw.metadata.config.FileUploadConfig",
"sourceType": "com.lw.metadata.config.FileUploadConfig"
},
{
"name": "map.test",
"type": "com.lw.metadata.config.MapTestConfig",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"properties": [
{
"name": "file.upload.max-size",
"type": "java.lang.String",
"description": "Maximum number of bytes per file",
"sourceType": "com.lw.metadata.config.FileUploadConfig",
"defaultValue": "1024M"
},
{
"name": "file.upload.reject-suffix",
"type": "java.lang.String",
"description": "The file suffix is not allowed.",
"sourceType": "com.lw.metadata.config.FileUploadConfig",
"defaultValue": "exe,jar"
},
{
"name": "map.test.data",
"type": "java.util.Map<java.lang.String,java.lang.Object>",
"description": "Tips for testing Map type data.",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"hints": [
{
"name": "map.test.data.keys",
"values": [
{
"value": "name",
"description": "The name of the person."
},
{
"value": "sex",
"description": "The sex of the person."
}
]
}
]
}

效果

SpringBoot 配置提示功能-LMLPHP

由此可以看到以下现象:

  • 代码中的默认值会自动生成到提示文件中,如:FileUploadConfig#maxSize
  • 代码中的注释会自动生成到提示文件中,如:FileUploadConfig#maxSize
  • additional-spring-configuration-metadata.json 文件中存在的提示会覆盖自动生成的对应属性,若自动生成的没有此属性则自动增加。

手动写提示文件

示例

{
"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate",
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
"sourceMethod": "getHibernate()"
}
],
"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.address",
"type": "java.net.InetAddress",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate.ddl-auto",
"type": "java.lang.String",
"description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
}
],
"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
}
]
}
]
}

groups

分组,将配置类分组。

可以按照文件来分组,即:将同一个配置文件的所有属性放在同一个组

nameStringY分组的完整名称
typeStringN分组数据类型的类名(如:使用@ConfigurationProperties注释的完整类名、使用@Bean注释的方法返回类型)
descriptionStringN分组的简短描述。
sourceTypeStringN提供分组来源的类名。
sourceMethodStringN提供分组的方法,包含括号和参数类型。

properties

提示主体,必须

nameStringY属性的完整名称。名称采用小写句点分隔格式,如:server.address
typeStringN属性数据类型的完整签名(如:java.lang.String)或完整的泛型类型(如:java.util.Map<java.util.String,acme.Myenum>)。此属性提示用户输入值得类型。原生类型在此处使用其包装类型(如:boolean使用java.lang.Boolean)。
descriptionStringN分组的简短描述。
sourceTypeStringN提供分组来源的类名。
defaultValueObjectN默认值。当属性为指定时使用。
deprecationDeprecationN指定属性是否已弃用。

deprecation属性如下:

levelStringN弃用级别,可以是 warning(默认值) 或 errorwarning:属性应该仍然可以使用;error:属性不保证可以使用
reasonStringN属性弃用的简短原因。
replacementStringN替换此弃用属性的新属性全名。可为空

以下示例来源于官方文档,展示了如何处理这种场景:

hints

辅助提示,非必须

nameStringY提示关联的属性的完整名称。名称是小写句点分隔格式(如:spring.mvc.servlet.path),如果属性关联map类型(如:system.contexts),提示可以关联map的键(system.contexts.keys)或者值(system.contexts.values)。
valuesValueHint[]N有效值集合。(下表详述)
providersValueProvider[]N提供者集合。(下表详述)

values 属性如下:

valueObjectY提示引用元素的有效值。如果属性是数组,value和description也可以是数组。
descriptionStringNvalue 对应的简短描述

ValueHint

对于Map类型的支持如下:

@ConfigurationProperties("sample")
public class SampleProperties { private Map<String,Integer> contexts;
// getters and setters
}
{"hints": [
{
"name": "sample.contexts.keys",
"values": [
{
"value": "sample1"
},
{
"value": "sample2"
}
]
}
]}

提示是对Map内每一对 key-value 的提示。

providers 属性如下:

nameStringN用于为提示所引用的元素提供其他内容帮助的 provider 的名称。
parametersJSON objectNprovider 所支持的任何其他参数(有关详细信息,请查看 provider 的文档)。

ValueProvider

一般用不到,建议跳过

下表总结了支持的 providers 列表:

any允许提供任何附加值。
class-reference自动完成项目中可用的类。通常由目标参数指定的基类约束。
handle-as处理属性,就像它是由必须的 target 参数定义的类型定义的一样。
logger-name自动完成有效的记录器名称和记录器组。通常,当前项目中可用的包和类名可以自动完成,也可以定义组。
spring-bean-reference自动完成当前项目中可用的bean名称。通常由 target 参数指定的基类约束。
spring-profile-name自动完成项目中可用的 spring 配置文件名称。

any

符合属性类型的所有值。

{"hints": [
{
"name": "system.state",
"values": [
{
"value": "on"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}

class-reference

提供以下参数:

targetString(Class)分配给值的类的全限定类名。通常用于筛选非候选类。
concretebooleantrue指定是否仅将具体类视为有效候选。
{"hints": [
{
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "javax.servlet.http.HttpServlet"
}
}
]
}
]}

handle-as

允许您将属性的类型替换为更高级的类型。

这通常在属性具有 java.lang.String 类型时发生,因为您不希望配置类依赖于不在类路径上的类。

targetString(Class)Y为属性考虑的类型的完全限定名。

可用的值如下:

  • 任何 java.lang.Enum: 列出属性的可能值。
  • java.nio.charset.Charset: 支持自动完成字符集/编码值(如 utf-8
  • java.util.Locale:自动完成区域设置(如:en_US)
  • org.springframework.util.MimeType:支持自动完成 content-type 值(如:text/plain
  • org.springframework.core.io.Resource: 支持自动完成spring的资源抽象以引用文件系统或类路径上的文件 (如:classpath:/sample.properties
{"hints": [
{
"name": "spring.liquibase.change-log",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]}

logger-name

支持以下参数:

groupbooleantrue指定是否应考虑已知组。

以下是 logging.level 属性。keys 是 logger 名,values 关联标准的 log levels 或 自定义的 level,

{"hints": [
{
"name": "logging.level.keys",
"values": [
{
"value": "root",
"description": "Root logger used to assign the default logging level."
},
{
"value": "sql",
"description": "SQL logging group including Hibernate SQL logger."
},
{
"value": "web",
"description": "Web logging group including codecs."
}
],
"providers": [
{
"name": "logger-name"
}
]
},
{
"name": "logging.level.values",
"values": [
{
"value": "trace"
},
{
"value": "debug"
},
{
"value": "info"
},
{
"value": "warn"
},
{
"value": "error"
},
{
"value": "fatal"
},
{
"value": "off"
} ],
"providers": [
{
"name": "any"
}
]
}
]}

spring-bean-reference

此 provider 自动完成在当前项目的配置中定义的bean。 支持以下参数:

targetString(Class)应该分配给候选对象的bean类的完全限定名。通常用于筛选非候选bean。

以下示例表示:spring.jmx.server 属性定义了使用 MBeanServer

{"hints": [
{
"name": "spring.jmx.server",
"providers": [
{
"name": "spring-bean-reference",
"parameters": {
"target": "javax.management.MBeanServer"
}
}
]
}
]}

spring-profile-name

此 provider 自动完成在当前项目的配置中定义的spring配置文件。

以下示例表示:spring.profiles.active属性可启用的配置文件名称。

{"hints": [
{
"name": "spring.profiles.active",
"providers": [
{
"name": "spring-profile-name"
}
]
}
]}

可重复的元数据项

自动生成提示文件

处理器获取用@configurationproperties注释的类和方法。 配置类中字段值的 javadoc 用于填充 description 属性。

@ConfigurationProperties(prefix="acme.messaging")
public class MessagingProperties { private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b")) ; private ContainerType = ContainerType.SIMPLE; // ... getter and setters public enum ContainerType {
SIMPLE,
DIRECT
}
}

为了提示上述属性的默认值,应该手动添加如下元数据:

{"properties": [
{
"name": "acme.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "acme.messaging.container-type",
"defaultValue": "simple"
}
]}

绑定属性

注解处理器自动将内部类视为嵌套属性。

@ConfigurationProperties(prefix="server")
public class ServerProperties {
private String name;
private Host host;
// ... getter and setters
public static class Host {
private String ip;
private int port;
// ... getter and setters
}
}

添加额外的元数据

参考资料

springboot 配置提示官方文档

公众号:逸飞兮(专注于 Java 领域知识的深入学习,从源码到原理,系统有序的学习)

SpringBoot 配置提示功能-LMLPHP

05-28 11:10