本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。

Spring Boot jar包括元数据文件,提供所有支持的配置属性的细节。 这些文件旨在让IDE开发人员在用户处理 application.propertiesapplication.yaml 文件时提供上下文帮助和 "代码自动补全"。

大部分的元数据文件是在编译时通过处理所有用 @ConfigurationProperties 注解的项目自动生成的。然而,对于角落里的案例或更高级的用例,也可以手动编写部分元数据

1. 元数据格式

配置元数据文件位于jars中 META-INF/spring-configuration-metadata.json 下。 它们使用JSON格式,项目分类为 “groups” 或 “properties”,附加值提示分类为 "hints",如以下例子所示。

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

每个 “property” 都是用户指定的一个配置项,有一个给定的值。 例如,server.portserver.address 可以在你的 application.properties/application.yaml 中指定,如下所示。

Properties
server.port=9090
server.address=127.0.0.1
Yaml
server:
  port: 9090
  address: 127.0.0.1

“groups” 是更高层次的项目,它本身并不指定一个值,而是为属性提供一个上下文分组。 例如,server.portserver.address 属性是 server 组的一部分。

并不要求每个 “property” 都有一个 “group”。 一些属性可能以它们自己的权利存在。

最后,“hints” 是用于帮助用户配置特定属性的额外信息。 例如,当开发者配置 spring.jpa.hibernate.ddl-auto 属性时,工具可以使用提示为 nonevalidateupdatecreatecreate-drop 值提供一些自动补全帮助。

1.1. Group 属性

包含在 groups 数组中的JSON对象可以包含下表中的属性。

Name 类型 目的

name

String

该组的全名。 这个属性是强制性的。

type

String

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

description

String

对该组的简短描述,可以显示给用户。 如果没有描述,可以省略。 建议描述是简短的段落,第一行提供一个简洁的摘要。 描述中的最后一行应以句号(.)结束。

sourceType

String

贡献这个组的来源的类名。 例如,如果这个组是基于一个 @Bean 方法,用 @ConfigurationProperties 注释,这个属性将包含包含该方法的 @Configuration 类的完全合格名称。 如果不知道源类型,该属性可以省略。

sourceMethod

String

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

1.2. Property 属性

properties 数组中包含的JSON对象可以包含下表中描述的属性。

Name 类型 目的

name

String

属性的全名。 名称采用小写的句号分隔形式(例如,server.address)。 这个属性是强制性的。

type

String

该属性的数据类型的完整签名(例如,java.lang.String),但也有完整的通用类型(例如 java.util.Map<java.lang.String,com.example.MyEnum>)。 你可以使用此属性来指导用户可以输入的值的类型。 为了保持一致性,基元的类型是通过使用其包装类型来指定的(例如,boolean 变成 java.lang.Boolean)。 请注意,这个类可能是一个复杂的类型,当值被绑定时,会从 String 转换过来。 如果该类型不知道,可以省略。

description

String

可以显示给用户的该property的简短描述。 如果没有描述,可以省略。 建议描述是简短的段落,第一行提供一个简洁的摘要。 描述中的最后一行应以句号(.)结束。

sourceType

String

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

defaultValue

Object

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

deprecation

Deprecation

指定该属性是否被废弃。 如果该字段没有被废弃,或者不知道该信息,可以省略。 下表提供了关于 deprecation 属性的更多细节。

每个 properties 元素的 deprecation 属性中包含的JSON对象可以包含以下属性。

Name Type 目的

level

String

废弃的级别,可以是 warning(默认)或 error。 当一个属性有一个 warning 的废弃级别时,它仍然应该在环境中被绑定。 然而,当它有一个 error 的废弃级别时,该属性不再被管理,也不被绑定。

reason

String

关于该属性被废弃的原因的简短描述。 如果没有原因,可以省略。 建议描述是简短的段落,第一行提供一个简洁的摘要。 描述中的最后一行应以句号(.)结束。

replacement

String

替换这个废弃的属性的属性的全名。 如果该属性没有替代物,可以省略。

在Spring Boot 1.3之前,可以使用单个 deprecated 布尔属性来代替 deprecation 元素。 这仍然是以弃用的方式支持的,不应该再使用。 如果没有原因和替换,应该设置一个空的 deprecation 对象。

弃用也可以在代码中通过向暴露弃用属性的getter添加 @DeprecatedConfigurationProperty 注解来声明性地指定。 例如,假设 my.app.target 属性被混淆并被重命名为 my.app.name。 下面的例子显示了如何处理这种情况。

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;

@ConfigurationProperties("my.app")
public class MyProperties {

    private String name;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Deprecated
    @DeprecatedConfigurationProperty(replacement = "my.app.name")
    public String getTarget() {
        return this.name;
    }

    @Deprecated
    public void setTarget(String target) {
        this.name = target;
    }

}
没有办法设置一个 levelwarning 总是被假定的,因为代码仍然在处理这个属性。

前面的代码确保被废弃的属性仍然有效(在幕后委托给 name 属性)。 一旦 getTargetsetTarget 方法可以从你的公共API中移除,元数据中的自动废弃提示也会消失。 如果你想保留一个提示,添加带有 error 废止级别的手动元数据可以确保用户仍然被告知该属性。 这样做在提供 replacement 的时候特别有用。

1.3. Hint 属性

包含在 hints 数组中的JSON对象可以包含下表中的属性。

Name 类型 目的

name

String

此提示所指向的属性的全名。 名称采用小写的句号分隔形式(如 spring.mvc.servlet.path)。 如果该属性指的是一个map(如 system.contexts),则该提示适用于该map的 keyssystem.contexts.keys)或该map的 valuessystem.contexts.values)。 这个属性是强制性的。

values

ValueHint[]

ValueHint 对象定义的有效值的列表(在下表中描述)。 每个条目都定义了值,并且可以有一个description。

providers

ValueProvider[]

ValueProvider 对象(本文稍后描述)定义的提供者列表。 每个条目都定义了提供者的名称和它的参数(如果有的话)。

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

Name 类型 目的

value

Object

提示所指的元素的一个有效值。 如果该属性的类型是一个数组,它也可以是一个数组的值。 这个属性是强制性的。

description

String

可以显示给用户的价值的简短描述。 如果没有描述,可以省略。 建议描述是简短的段落,第一行提供一个简洁的摘要。 描述中的最后一行应以句号(.)结束。

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

Name 类型 目的

name

String

提供者的名称,用于为提示所指的元素提供额外的内容帮助。

parameters

JSON object

提供者支持的任何其他参数(查看提供者的文档以了解更多细节)。

1.4. 重复的元数据项目

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

2. 提供人工提示

为了改善用户体验,并进一步帮助用户配置一个给定的属性,你可以提供额外的元数据,这些元数据。

  • 描述一个属性的潜在值的列表。

  • 关联一个提供者,为一个属性附加一个定义良好的语义,这样一个工具就可以根据项目的上下文发现潜在值的列表。

2.1. Value 提示

每个提示的 name 属性指的是一个属性的名称。在前面显示的初始例子中,我们为 spring.jpa.hibernate.ddl-auto 属性提供了五个值:none, validate, update, createcreate-drop。每个值也可以有一个描述。

如果你的属性是 Map 类型,你可以为key和value提供提示(但不是为map本身)。 特殊的 .keys.values 后缀必须分别指代key和value。

假设一个 my.contexts 将神奇的 String 值映射成一个整数,如下例所示。

import java.util.Map;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("my")
public class MyProperties {

    private Map<String, Integer> contexts;

    // getters/setters ...

    public Map<String, Integer> getContexts() {
        return this.contexts;
    }

    public void setContexts(Map<String, Integer> contexts) {
        this.contexts = contexts;
    }

}

魔法值是(在这个例子中)是 sample1sample2。为了给key提供额外的内容帮助,你可以在 模块的手动元数据中添加以下JSON。

{"hints": [
    {
        "name": "my.contexts.keys",
        "values": [
            {
                "value": "sample1"
            },
            {
                "value": "sample2"
            }
        ]
    }
]}
我们建议你用 Enum 来代替这两个值。 如果你的IDE支持它,这是迄今为止最有效的自动补全方法。

2.2. Value 提供者

提供者是给属性附加语义的一种强大方式。 在本节中,我们定义了官方的提供者,你可以在自己的提示中使用。 然而,你最喜欢的IDE可能会实现其中的一些,或者不实现这些。 另外,它最终也可以提供自己的。

由于这是一个新功能,IDE供应商必须赶上它的工作方式。 采用时间自然不同。

下表概述了所支持的供应商名单。

Name 说明

any

允许提供任何额外的Value。

class-reference

自动完成项目中的可用类。 通常由 target 参数指定的基类来约束。

handle-as

处理该属性,就像它被强制性的 target 参数所定义的类型所定义一样。

logger-name

自动完成有效的logger名称和logger group。通常情况下,当前项目中可用的包和类的名称以及定义的组都可以被自动完成。

spring-bean-reference

自动完成当前项目中可用的Bean类名称。 通常受基类的限制,基类由 target 参数指定。

spring-profile-name

自动补全项目中可用的Spring配置文件名称。

对于一个给定的属性,只能有一个提供者,但你可以指定几个提供者,如果它们都能以某种方式管理该属性。 请确保将最强大的提供者放在首位,因为IDE必须使用它能处理的JSON部分中的第一个提供者。 如果不支持某个给定属性的提供者,也不会提供特殊的内容协助。

2.2.1. Any

特殊的 any 提供者的值允许提供任何额外的值。 如果支持的话,应该应用基于属性类型的常规值验证。

如果你有一个值的列表,并且任何额外的值仍应被认为是有效的,则通常使用这个提供者。

下面的例子提供了 onoff 作为 system.state 的自动补全值。

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

注意,在前面的例子中,任何其他的值也是允许的。

2.2.2. 类参考(Class Reference)

类参考 提供者自动完成项目中可用的类。 这个提供者支持以下参数。

参数 类型 默认值 说明

target

String (Class)

none

应该可以分配给所选值的类的完全名称。 通常用于过滤掉非候选类。 注意,这个信息可以由类型本身提供,通过暴露一个具有适当上界的类。

concrete

boolean

true

指定是否只考虑具体的类作为有效的候选人。

下面的元数据片段对应于标准的 server.servlet.jsp.class-name 属性,它定义了要使用的 JspServlet 类名。

{"hints": [
    {
        "name": "server.servlet.jsp.class-name",
        "providers": [
            {
                "name": "class-reference",
                "parameters": {
                    "target": "jakarta.servlet.http.HttpServlet"
                }
            }
        ]
    }
]}

2.2.3. 处理方式(Handle As)

handle-as提供者让你把属性的类型替换成一个更高级的类型。 这通常发生在属性具有 java.lang.String 类型时,因为你不希望你的配置类依赖可能不在classpath上的类。 该提供者支持以下参数。

参数 类型 默认值 说明

target

String (Class)

none

要考虑的属性类型的完全名称。 这个参数是强制性的。

可以使用以下类型。

  • 任何 java.lang.Enum:列出该属性的可能值。 (我们建议用 Enum 类型来定义属性,因为不需要进一步的提示,IDE就能自动完成数值。)

  • java.nio.charset.Charset:支持自动补全字符集/编码值(如 UTF-8)。

  • java.util.Locale: 自动补全Locale(如 en_US)。

  • org.springframework.util.MimeType: 支持内容类型值的自动补全(如 text/plain)。

  • org.springframework.core.io.Resource: 支持Spring资源抽象的自动补全,以引用文件系统或classpath上的文件(如 classpath:/sample.properties)。

如果可以提供多个值,请使用 CollectionArray 类型来告诉IDE。

下面的元数据片段对应于标准的 spring.liquibase.change-log 属性,它定义了要使用的更新日志的路径。 它实际上是作为 org.springframework.core.io.Resource 在内部使用的,但不能以这种方式公开,因为我们需要保留原始的String值来传递给Liquibase的API。

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

2.2.4. Logger Name

Logger name 提供者自补全成有效的 Logger name 和 logger group。通常情况下,当前项目中可用的包和类的名称可以被自动补全。如果启用了组(默认),并且如果在配置中确定了一个自定义的logger group,那么应该为其提供自动补全。特定的框架可能有额外的神奇的 logger name,也可以被支持。

该provider支持以下参数。

参数 类型 默认值 说明

group

boolean

true

指定是否应考虑已知群体。

由于logger name的名字可以是任何任意的名字,这个提供者应该允许任何值,但可以突出显示项目的classpath中没有的有效包和类的名字。

下面的元数据片段对应于标准的 logging.level 属性。 key 是 logger name,value对应于标准日志级别或任何自定义级别。 由于Spring Boot定义了一些开箱即用的日志组,因此为这些组添加了专门的值提示。

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

2.2.5. Spring Bean Reference

spring-bean-reference提供者自动补全在当前项目的配置中定义的bean。 该提供者支持以下参数。

参数 类型 默认值 说明

target

String (Class)

none

应该可以分配给候选者的Bean类的完全限定名称。 通常用于过滤掉非候选Bean。

下面的元数据片段对应于标准的 spring.jmx.server 属性,它定义了要使用的 MBeanServer bean的名称。

{"hints": [
    {
        "name": "spring.jmx.server",
        "providers": [
            {
                "name": "spring-bean-reference",
                "parameters": {
                    "target": "javax.management.MBeanServer"
                }
            }
        ]
    }
]}
binder不知道元数据的存在。 如果你提供了这个提示,你仍然需要把Bean的名字转换成实际的Bean引用,由 ApplicationContext 使用。

2.2.6. Spring Profile Name

spring-profile-name提供者自动完成当前项目的配置中定义的Spring配置文件。

下面的元数据片段对应于标准的 spring.profiles.active 属性,该属性定义了要启用的Spring配置文件的名称。

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

3. 通过使用注解处理器(Annotation Processor)生成你自己的元数据 Metadata

你可以通过使用 spring-boot-configuration-processor jar,轻松地从用 @ConfigurationProperties 注解的项目中生成你自己的配置元数据文件。 这个jar包括一个Java注解处理器,在你的项目被编译时被调用。

3.1. 配置注解处理器

要使用该处理器,需要包含对 spring-boot-configuration-processor 的依赖。

在Maven中,该依赖关系应被声明为可选的,如以下例子所示。

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

在Gradle中,应该在 annotationProcessor 配置中声明该依赖关系,如下面的例子所示。

dependencies {
    annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
}

如果你使用 additional-spring-configuration-metadata.json 文件, compileJava 任务应该被配置为依赖 processResources 任务,如以下例子所示。

tasks.named('compileJava') {
    inputs.files(tasks.named('processResources'))
}

这种依赖性确保了在编译期间注解处理器运行时,额外的元数据是可用的。

如果你在你的项目中使用AspectJ,你需要确保注解处理器只运行一次。 有几种方法可以做到这一点。 在Maven中,你可以明确配置 maven-apt-plugin,并只在那里添加对注解处理器的依赖。 你也可以让AspectJ插件运行所有处理,并在 maven-compiler-plugin 配置中禁用注解处理,如下所示。

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

如果你在项目中使用Lombok,你需要确保其注解处理器在 spring-boot-configuration-processor 之前运行。 要用Maven做到这一点,你可以使用Maven编译器插件的 annotationProcessors 属性按正确顺序列出注解处理器。 如果不使用该属性,注解处理器由classpath上的可用依赖项拾取,请确保 lombok 依赖项定义在 spring-boot-configuration-processor 依赖项之前。

3.2. 自动生成元数据

该处理器同时拾取带有 @ConfigurationProperties 注解的类和方法。

如果该类有一个单一参数的构造函数,每个构造函数参数创建一个属性,除非该构造函数被注解为 @Autowired。 如果该类有一个明确用 @ConstructorBinding 注解的构造函数,则为该构造函数的每个构造函数参数创建一个属性。 否则,属性是通过标准的getter和setter发现的,并对集合和map类型进行特殊处理(即使只有一个getter存在,也会被发现)。 注解处理器也支持使用 @Data@Value@Getter@Setter 等lombok注解。

请考虑以下例子。

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "my.server")
public class MyServerProperties {

    /**
     * Name of the server.
     */
    private String name;

    /**
     * IP address to listen to.
     */
    private String ip = "127.0.0.1";

    /**
     * Port to listener to.
     */
    private int port = 9797;

    // getters/setters ...

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIp() {
        return this.ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return this.port;
    }

    public void setPort(int port) {
        this.port = port;
    }
    // fold:off

这暴露了三个属性,其中 my.server.name 没有默认值,my.server.ipmy.server.port 分别默认为 "127.0.0.1"9797。 关于字段的Javadoc被用来填充 description 属性。例如,my.server.ip 的描述是 "IP address to listen to."。

你应该只使用纯文本的 @ConfigurationProperties 字段Javadoc,因为它们在被添加到JSON之前没有被处理。

注解处理器应用一些启发式方法来从源模型中提取默认值。 默认值必须以静态方式提供。特别是,不要引用另一个类中定义的常量。 另外,注解处理器不能自动检测 EnumCollections 的默认值。

对于无法检测到默认值的情况,应该提供手动元数据。考虑下面的例子。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "my.messaging")
public class MyMessagingProperties {

    private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b"));

    private ContainerType containerType = ContainerType.SIMPLE;

    // getters/setters ...

    public List<String> getAddresses() {
        return this.addresses;
    }

    public void setAddresses(List<String> addresses) {
        this.addresses = addresses;
    }

    public ContainerType getContainerType() {
        return this.containerType;
    }

    public void setContainerType(ContainerType containerType) {
        this.containerType = containerType;
    }

    public enum ContainerType {

        SIMPLE, DIRECT

    }

}

为了记录上述类中属性的默认值,你可以在模块的手动元数据中添加以下内容。

{"properties": [
    {
        "name": "my.messaging.addresses",
        "defaultValue": ["a", "b"]
    },
    {
        "name": "my.messaging.container-type",
        "defaultValue": "simple"
    }
]}
只需要属性的 name 来记录现有属性的额外元数据。

3.2.1. 嵌套属性

注解处理器自动将内部类视为嵌套属性。 与其在命名空间的根部记录 ipport,我们可以为它创建一个子命名空间。 考虑一下最新的例子。

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "my.server")
public class MyServerProperties {

    private String name;

    private Host host;

    // getters/setters ...

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Host getHost() {
        return this.host;
    }

    public void setHost(Host host) {
        this.host = host;
    }

    public static class Host {

        private String ip;

        private int port;

        // getters/setters ...

        public String getIp() {
            return this.ip;
        }

        public void setIp(String ip) {
            this.ip = ip;
        }

        public int getPort() {
            return this.port;
        }

        public void setPort(int port) {
            this.port = port;
        }

    }

}

前面的例子为 my.server.namemy.server.host.ipmy.server.host.port 属性产生元数据信息。 你可以在一个字段上使用 @NestedConfigurationProperty 注解来表示一个普通的(非内部)类应该被当作是嵌套的。

这对collection和map没有影响,因为这些类型被自动识别,并且为它们中的每一个生成了一个单一的元数据属性。

3.3. 添加额外的元数据

Spring Boot对配置文件的处理相当灵活,通常情况下,可能存在未与 @ConfigurationProperties bean 绑定的属性。 你也可能需要调整现有键的一些属性。 为了支持这种情况并让你提供自定义的 "hints",注解处理器会自动将 META-INF/additional-spring-configuration-metadata.json 中的项目合并到主元数据文件中。

如果你引用的是一个已经被自动检测到的属性,那么描述、默认值和废弃信息将被覆盖,如果指定的话。 如果手动属性声明在当前模块中没有被识别,它将被作为一个新的属性添加。

additional-spring-configuration-metadata.json 文件的格式与常规的 spring-configuration-metadata.json 完全相同。 附加属性文件是可选的。 如果你没有任何附加属性,请不要添加该文件。