目的

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

springboot jar 包含提供所有支持的配置属性细节的元数据文件。文件的目的是为了让 IDE 开发者在用户使用 application.propertiesapplication.yml 文件时提供上下文帮助和代码补全。

大多数元数据文件是在编译时通过处理用 @ConfigurationProperties 注释的所有项自动生成的。也可以手动编写部分元数据。

版本

参考 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."
}
]
}
]
}

效果

由此可以看到以下现象:

  • 代码中的默认值会自动生成到提示文件中,如: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

分组,将配置类分组。

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

属性 类型 是否必须 用途
name String Y 分组的完整名称
type String N 分组数据类型的类名(如:使用@ConfigurationProperties注释的完整类名、使用@Bean注释的方法返回类型)
description String N 分组的简短描述。
sourceType String N 提供分组来源的类名。
sourceMethod String N 提供分组的方法,包含括号和参数类型。

properties

提示主体,必须

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

deprecation属性如下:

属性 类型 是否必须 用途
level String N 弃用级别,可以是 warning(默认值) 或 errorwarning:属性应该仍然可以使用;error:属性不保证可以使用
reason String N 属性弃用的简短原因。
replacement String N 替换此弃用属性的新属性全名。可为空

注意:Spring Boot 1.3 版本之前,是使用 boolean 类型的 deprecated

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

@ConfigurationProperties("app.acme")
public class AcmeProperties { private String name; public String getName() { ... } public void setName(String name) { ... } @DeprecatedConfigurationProperty(replacement = "app.acme.name")
@Deprecated
public String getTarget() {
return getName();
} @Deprecated
public void setTarget(String target) {
setName(target);
}
}

一旦 getTargetsetTarget 方法从公共 API 中删除,元数据中的自动弃用提示也会消失。 如果要保留提示,则添加具有 error 弃用级别的手动元数据可以确保用户仍然了解该属性。在提供替代品时,这样做特别有用。

hints

辅助提示,非必须

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

values 属性如下:

属性 类型 是否必须 用途
value Object Y 提示引用元素的有效值。如果属性是数组,value和description也可以是数组。
description String N value 对应的简短描述

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 的提示。

.keys.values 前缀必须分别关联 Map 的 keys 和 values。

providers 属性如下:

属性 类型 是否必须 用途
name String N 用于为提示所引用的元素提供其他内容帮助的 provider 的名称。
parameters JSON object N provider 所支持的任何其他参数(有关详细信息,请查看 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

提供以下参数:

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

handle-as

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

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

参数 类型 默认值 描述
target String(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

注意:如果要提供多个值,用 Collection 或 数组类型

{"hints": [
{
"name": "spring.liquibase.change-log",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]}

logger-name

logger-name provider 自动完成有效的记录器名称和记录器组。 通常,当前项目中可用的包和类名可以自动完成。 如果组已启用(默认),并且配置中标识了自定义记录器组,则应提供该组的自动完成。

支持以下参数:

参数 类型 默认值 描述
group boolean true 指定是否应考虑已知组。

由于记录器名称可以是任意名称,此 provider 应允许任何值,但可以突出显示项目的类路径中不可用的有效包和类名。

以下是 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。 支持以下参数:

参数 类型 默认值 描述
target String(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"
}
]
}
]}

可重复的元数据项

具有相同“property”和“group”名称的对象可以在元数据文件中多次出现。 例如,可以将两个单独的类绑定到同一前缀,每个类都有可能重叠的属性名。 虽然多次出现在元数据中的相同名称不应是常见的,但元数据的使用者应注意确保他们支持该名称。

自动生成提示文件

通过使用 spring-boot-configuration-processor jar,您可以从用 @ConfigurationProperties 注释的类中轻松生成自己的配置元数据文件。 jar包含一个java注释处理器,在编译项目时调用它。 用此处理器,需要引入 spring-boot-configuration-processor 依赖。

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

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

注意:仅仅只应将简单文本与@configurationproperties字段javadoc一起使用,因为在将它们添加到json之前不会对它们进行处理。

如果类有一个“至少一个参数”的构造函数,则为每个构造函数参数创建一个属性。 否则,通过标准getter和setter来发现属性,这些getter和setter对集合类型进行了特殊处理(即使只有getter存在,也会检测到)。

注解处理器还支持使用@data、@getter和@setter 的 lombok 注解。

注解处理器无法自动检测 EnumCollections 的默认值。在集合或枚举属性具有非空默认值的情况下,应提供手动元数据。

@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"
}
]}

注意: 如果在项目中使用 AspectJ,则需要确保注解处理器只运行一次。 使用 Maven 时, 可以显式地配置 maven-apt-plugin插件,并仅在那里向注解处理器添加依赖项。 还可以让 AspectJ 插件运行于所有的处理且在 maven-compiler-pluginconfiguration 中禁用注解处理,如下:

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<proc>none</proc>
</configuration>
</plugin>

绑定属性

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

@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
}
}

上述示例生成 server.nameserver.host.ipserver.host.port 属性的元数据信息。 可以在字段上使用@NestedconfigurationProperty 注解来指示应将常规(非内部)类视为嵌套类。

注意: 这对集合和映射没有影响,因为这些类型是自动标识的,并且为每个类型生成一个元数据属性。

添加额外的元数据

Spring Boot 的配置文件处理非常灵活,通常情况下,可能存在不绑定到 @ConfigurationProperties bean的属性。 您还可能需要调整现有key的某些属性,为了支持这种情况并让您提供自定义的“提示”,注解处理器会自动将 META-INF/additional-spring-configuration-metadata.json 中的提示项合并到主要元数据文件(spring-configuration-metadata.json)中

如果引用已自动检测到的属性,则将覆盖描述、默认值和弃用信息(如果指定)。 如果当前模块中没有标识手动属性中的声明,则将其作为新属性添加。

additional-spring-configuration-metadata.json 文件的格式与 spring-configuration-metadata.json 文件一样。 附加属性文件是可选的。如果没有任何其他属性,就不要添加文件。

参考资料

springboot 配置提示官方文档

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

SpringBoot 配置提示功能的更多相关文章

  1. 使用 SpringBoot 配置发送邮件功能

    1.使用 SpringBoot 配置发送邮件功能 项目总体结构 用户表设计 SET FOREIGN_KEY_CHECKS=0; CREATE DATABASE sample; USE sample; ...

  2. Eclipse配置PHP及自动提示功能

    Eclipse是一个开发工具,具有强大的插件功能,虽然用于Java理所当然,但为PHP所用,也为尝不可.虽然我一直用的是notepad,但发现开发工具也可以省去一些不必要的记忆. 言归正传,下面就来实 ...

  3. eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能(同时解决自动补全变量名的问题)?

    对于编程人员来说,要记住大量的类名或类方法的名字,着实不是一件容易的事情.如果要IDE能够自动补全代码,那将为我们编程人员带来很大帮助. eclipse代码里面的代码提示功能默认是关闭的,只有输入“. ...

  4. SpringBoot自定义配置以及IDEA配置提示

    本篇文章将会讲解在springboot项目中如何实现自定义配置以及在IDEA或者Eclipse中实现配置项提示,就像spring的配置提示一样 想要做到这点其实非常简单 1.添加依赖 <depe ...

  5. VIM配置自动提示功能

        问题描述:                  使用VIM作为Linux下的IDE,但是VIM默认情况下不支持自动代码提示功能,因此希望安装插件实现自动提示功能,目前找到的自动提示工具,非常好用 ...

  6. springboot配置详解

    springboot配置详解 Author:SimpleWu properteis文件属性参考大全 springboot默认加载配置 SpringBoot使用两种全局的配置文件,全局配置文件可以对一些 ...

  7. SpringBoot配置(1) 配置文件application&yml

    SpringBoot配置(1) 配置文件application&yml 一.配置文件 1.1 配置文件 SpringBoot使用一个全局的配置文件,配置文件名是固定的. application ...

  8. SpringBoot 配置 Tomcat SSL

    SpringBoot 配置 Tomcat SSL SSL(Secure Sockets Layer , 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密 ...

  9. eclipse自动提示功能没了的解决办法(转载)

    eclipse自动提示功能没了的解决办法 标签: eclipse联想 2012-08-09 14:32 24687人阅读 评论(7) 收藏 举报  分类: Android(38)  版权声明:本文为博 ...

随机推荐

  1. .netCore+Vue 搭建的简捷开发框架 (4)--NetCore 基础

    书接上文:上一节中,我们已经实现Services 层.(https://www.cnblogs.com/xuzhencheng/p/11424751.html) 但是具体要如何将服务依赖注入进来呢?继 ...

  2. Spring 梳理-运行时动态注入bean

    动态注入的方法 使用占位符 使用Spring表达式

  3. tomcat设定shared lib共享同样的jar

    在项目越来越多的时候,部署在tomcat的发布包也会越来越多,这样难免有很多相同的jar会被加载,占用大量的永久存续区内存,通过设定shared lib来控制相同的jar只加载一个,这样有以下好处: ...

  4. java @postconstruct初始化注解使用

    1.从Java EE 5规范开始,Servlet中增加了两个影响Servlet生命周期的注解(Annotion):@PostConstruct和@PreDestroy.这两个注解被用来修饰一个非静态的 ...

  5. ZK集群的Leader选举源码阅读

    前言 ZooKeeper对Zab协议的实现有自己的主备模型,即Leader和learner(Observer + Follower),有如下几种情况需要进行领导者的选举工作 情形1: 集群在启动的过程 ...

  6. window连接远程服务器报函数不支持之解决方案

    1.针对window10系统 Windows+R,输入cmd,输入gpedit.msc 然后就可以启动远程连接了 2.针对window7用户 没有上述的第一个操作选项 1. 打开注册表,快捷输入 “r ...

  7. scalikejdbc 学习笔记(2)

    使用scalikejdbc config (src\main\resources) # MySQL(dev) dev.db.default.driver="com.mysql.jdbc.Dr ...

  8. 02-05 scikit-learn库之线性回归

    目录 scikit-learn库之线性回归 一.LinearRegression 1.1 使用场景 1.2 代码 1.3 参数详解 1.4 属性 1.5 方法 1.5.1 报告决定系数 二.ARDRe ...

  9. 1046 Shortest Distance (20 分)

    1046 Shortest Distance (20 分) The task is really simple: given N exits on a highway which forms a si ...

  10. Java虚拟机重点知识归纳总结

    一.     JVM内存分区 分为程序计数器.虚拟机栈.本地方法栈.Java堆.方法区5个区域 其中Java堆和方法区是线程共享的,虚拟机栈.本地方法栈.程序计数器是线程隔离的. 程序计数器: 1.可 ...