本站(springdoc.cn)中的内容来源于 spring.io ,原始版权归属于 spring.io。由 springdoc.cn 进行翻译,整理。可供个人学习、研究,未经许可,不得进行任何转载、商用或与之相关的行为。 商标声明:Spring 是 Pivotal Software, Inc. 在美国以及其他国家的商标。 |
Spring Boot jar包括元数据文件,提供所有支持的配置属性的细节。
这些文件旨在让IDE开发人员在用户处理 application.properties
或 application.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.port
和 server.address
可以在你的 application.properties
/application.yaml
中指定,如下所示。
server.port=9090
server.address=127.0.0.1
server:
port: 9090
address: 127.0.0.1
“groups” 是更高层次的项目,它本身并不指定一个值,而是为属性提供一个上下文分组。
例如,server.port
和 server.address
属性是 server
组的一部分。
并不要求每个 “property” 都有一个 “group”。 一些属性可能以它们自己的权利存在。 |
最后,“hints” 是用于帮助用户配置特定属性的额外信息。
例如,当开发者配置 spring.jpa.hibernate.ddl-auto
属性时,工具可以使用提示为 none
、validate
、update
、create
和 create-drop
值提供一些自动补全帮助。
1.1. Group 属性
包含在 groups
数组中的JSON对象可以包含下表中的属性。
Name | 类型 | 目的 |
---|---|---|
|
String |
该组的全名。 这个属性是强制性的。 |
|
String |
该组的数据类型的类名。
例如,如果该组是基于一个用 |
|
String |
对该组的简短描述,可以显示给用户。
如果没有描述,可以省略。
建议描述是简短的段落,第一行提供一个简洁的摘要。
描述中的最后一行应以句号( |
|
String |
贡献这个组的来源的类名。
例如,如果这个组是基于一个 |
|
String |
贡献这个组的方法的全名(包括括号和参数类型)(例如,一个 |
1.2. Property 属性
properties
数组中包含的JSON对象可以包含下表中描述的属性。
Name | 类型 | 目的 |
---|---|---|
|
String |
属性的全名。
名称采用小写的句号分隔形式(例如, |
|
String |
该属性的数据类型的完整签名(例如, |
|
String |
可以显示给用户的该property的简短描述。
如果没有描述,可以省略。
建议描述是简短的段落,第一行提供一个简洁的摘要。
描述中的最后一行应以句号( |
|
String |
贡献此属性的来源的类名。
例如,如果该属性来自于一个用 |
|
Object |
默认值,如果没有指定该属性,则使用该值。 如果该属性的类型是一个数组,它可以是一个数组的值。 如果默认值是未知的,它可以被省略。 |
|
Deprecation |
指定该属性是否被废弃。
如果该字段没有被废弃,或者不知道该信息,可以省略。
下表提供了关于 |
每个 properties
元素的 deprecation
属性中包含的JSON对象可以包含以下属性。
Name | Type | 目的 |
---|---|---|
|
String |
废弃的级别,可以是 |
|
String |
关于该属性被废弃的原因的简短描述。
如果没有原因,可以省略。
建议描述是简短的段落,第一行提供一个简洁的摘要。
描述中的最后一行应以句号( |
|
String |
替换这个废弃的属性的属性的全名。 如果该属性没有替代物,可以省略。 |
在Spring Boot 1.3之前,可以使用单个 deprecated 布尔属性来代替 deprecation 元素。
这仍然是以弃用的方式支持的,不应该再使用。
如果没有原因和替换,应该设置一个空的 deprecation 对象。
|
弃用也可以在代码中通过向暴露弃用属性的getter添加 @DeprecatedConfigurationProperty
注解来声明性地指定。
例如,假设 my.app.target
属性被混淆并被重命名为 my.app.name
。
下面的例子显示了如何处理这种情况。
@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;
}
}
没有办法设置一个 level 。
warning 总是被假定的,因为代码仍然在处理这个属性。
|
前面的代码确保被废弃的属性仍然有效(在幕后委托给 name
属性)。
一旦 getTarget
和 setTarget
方法可以从你的公共API中移除,元数据中的自动废弃提示也会消失。
如果你想保留一个提示,添加带有 error
废止级别的手动元数据可以确保用户仍然被告知该属性。
这样做在提供 replacement
的时候特别有用。
1.3. Hint 属性
包含在 hints
数组中的JSON对象可以包含下表中的属性。
Name | 类型 | 目的 |
---|---|---|
|
String |
此提示所指向的属性的全名。
名称采用小写的句号分隔形式(如 |
|
ValueHint[] |
由 |
|
ValueProvider[] |
由 |
每个 hint
元素的 values
属性中包含的JSON对象可以包含下表中描述的属性。
Name | 类型 | 目的 |
---|---|---|
|
Object |
提示所指的元素的一个有效值。 如果该属性的类型是一个数组,它也可以是一个数组的值。 这个属性是强制性的。 |
|
String |
可以显示给用户的价值的简短描述。
如果没有描述,可以省略。
建议描述是简短的段落,第一行提供一个简洁的摘要。
描述中的最后一行应以句号( |
每个 hint
元素的 providers
属性中包含的JSON对象可以包含下表中描述的属性。
Name | 类型 | 目的 |
---|---|---|
|
String |
提供者的名称,用于为提示所指的元素提供额外的内容帮助。 |
|
JSON object |
提供者支持的任何其他参数(查看提供者的文档以了解更多细节)。 |
2. 提供人工提示
为了改善用户体验,并进一步帮助用户配置一个给定的属性,你可以提供额外的元数据,这些元数据。
-
描述一个属性的潜在值的列表。
-
关联一个提供者,为一个属性附加一个定义良好的语义,这样一个工具就可以根据项目的上下文发现潜在值的列表。
2.1. Value 提示
每个提示的 name
属性指的是一个属性的名称。在前面显示的初始例子中,我们为 spring.jpa.hibernate.ddl-auto
属性提供了五个值:none
, validate
, update
, create
和 create-drop
。每个值也可以有一个描述。
如果你的属性是 Map
类型,你可以为key和value提供提示(但不是为map本身)。
特殊的 .keys
和 .values
后缀必须分别指代key和value。
假设一个 my.contexts
将神奇的 String
值映射成一个整数,如下例所示。
@ConfigurationProperties("my")
public class MyProperties {
private Map<String, Integer> contexts;
}
魔法值是(在这个例子中)是 sample1
和 sample2
。为了给key提供额外的内容帮助,你可以在 模块的手动元数据中添加以下JSON。
{"hints": [
{
"name": "my.contexts.keys",
"values": [
{
"value": "sample1"
},
{
"value": "sample2"
}
]
}
]}
我们建议你用 Enum 来代替这两个值。
如果你的IDE支持它,这是迄今为止最有效的自动补全方法。
|
2.2. Value 提供者
提供者是给属性附加语义的一种强大方式。 在本节中,我们定义了官方的提供者,你可以在自己的提示中使用。 然而,你最喜欢的IDE可能会实现其中的一些,或者不实现这些。 另外,它最终也可以提供自己的。
由于这是一个新功能,IDE供应商必须赶上它的工作方式。 采用时间自然不同。 |
下表概述了所支持的供应商名单。
Name | 说明 |
---|---|
|
允许提供任何额外的Value。 |
|
自动完成项目中的可用类。
通常由 |
|
处理该属性,就像它被强制性的 |
|
自动完成有效的logger名称和logger group。通常情况下,当前项目中可用的包和类的名称以及定义的组都可以被自动完成。 |
|
自动完成当前项目中可用的Bean类名称。
通常受基类的限制,基类由 |
|
自动补全项目中可用的Spring配置文件名称。 |
对于一个给定的属性,只能有一个提供者,但你可以指定几个提供者,如果它们都能以某种方式管理该属性。 请确保将最强大的提供者放在首位,因为IDE必须使用它能处理的JSON部分中的第一个提供者。 如果不支持某个给定属性的提供者,也不会提供特殊的内容协助。 |
2.2.1. Any
特殊的 any 提供者的值允许提供任何额外的值。 如果支持的话,应该应用基于属性类型的常规值验证。
如果你有一个值的列表,并且任何额外的值仍应被认为是有效的,则通常使用这个提供者。
下面的例子提供了 on
和 off
作为 system.state
的自动补全值。
{"hints": [
{
"name": "system.state",
"values": [
{
"value": "on"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}
注意,在前面的例子中,任何其他的值也是允许的。
2.2.2. 类参考(Class Reference)
类参考 提供者自动完成项目中可用的类。 这个提供者支持以下参数。
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
|
|
none |
应该可以分配给所选值的类的完全名称。 通常用于过滤掉非候选类。 注意,这个信息可以由类型本身提供,通过暴露一个具有适当上界的类。 |
|
|
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上的类。
该提供者支持以下参数。
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
|
|
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
)。
如果可以提供多个值,请使用 Collection 或 Array 类型来告诉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支持以下参数。
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
|
|
|
指定是否应考虑已知群体。 |
由于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。 该提供者支持以下参数。
参数 | 类型 | 默认值 | 说明 |
---|---|---|---|
|
|
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 使用。
|
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中,你可以明确配置
|
如果你在项目中使用Lombok,你需要确保其注解处理器在 |
3.2. 自动生成元数据
该处理器同时拾取带有 @ConfigurationProperties
注解的类和方法。
如果该类有一个单一参数的构造函数,每个构造函数参数创建一个属性,除非该构造函数被注解为 @Autowired
。
如果该类有一个明确用 @ConstructorBinding
注解的构造函数,则为该构造函数的每个构造函数参数创建一个属性。
否则,属性是通过标准的getter和setter发现的,并对集合和map类型进行特殊处理(即使只有一个getter存在,也会被发现)。
注解处理器也支持使用 @Data
、@Value
、@Getter
和 @Setter
等lombok注解。
请考虑以下例子。
@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;
这暴露了三个属性,其中 my.server.name
没有默认值,my.server.ip
和 my.server.port
分别默认为 "127.0.0.1"
和 9797
。
关于字段的Javadoc被用来填充 description
属性。例如,my.server.ip
的描述是 "IP address to listen to."。
你应该只使用纯文本的 @ConfigurationProperties 字段Javadoc,因为它们在被添加到JSON之前没有被处理。
|
注解处理器应用一些启发式方法来从源模型中提取默认值。
默认值必须以静态方式提供。特别是,不要引用另一个类中定义的常量。
另外,注解处理器不能自动检测 Enum
和 Collections
的默认值。
对于无法检测到默认值的情况,应该提供手动元数据。考虑下面的例子。
@ConfigurationProperties(prefix = "my.messaging")
public class MyMessagingProperties {
private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b"));
private ContainerType containerType = ContainerType.SIMPLE;
public enum ContainerType {
SIMPLE, DIRECT
}
}
为了记录上述类中属性的默认值,你可以在模块的手动元数据中添加以下内容。
{"properties": [
{
"name": "my.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "my.messaging.container-type",
"defaultValue": "simple"
}
]}
只需要属性的 name 来记录现有属性的额外元数据。
|
3.2.1. 嵌套属性
注解处理器自动将内部类视为嵌套属性。
与其在命名空间的根部记录 ip
和 port
,我们可以为它创建一个子命名空间。
考虑一下最新的例子。
@ConfigurationProperties(prefix = "my.server")
public class MyServerProperties {
private String name;
private Host host;
public static class Host {
private String ip;
private int port;
}
}
前面的例子为 my.server.name
、my.server.host.ip
和 my.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
完全相同。
附加属性文件是可选的。
如果你没有任何附加属性,请不要添加该文件。