此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Boot 3.4.0! |
使用 Annotation Processor 生成您自己的元数据
您可以使用 jar 轻松地从带有 @ConfigurationProperties
注解的项目生成自己的配置元数据文件。
该 jar 包括一个 Java 注释处理器,该处理器在编译项目时调用。spring-boot-configuration-processor
配置 Annotation 处理器
要使用处理器,请包含对 的依赖项。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'))
}
此依赖关系可确保在编译期间 Comments 处理器运行时其他元数据可用。
如果你在你的项目中使用 AspectJ,你需要确保 Comments 处理器只运行一次。
有几种方法可以做到这一点。
使用 Maven,您可以显式配置,并仅在其中将依赖项添加到注释处理器。
你也可以让 AspectJ 插件运行所有处理并在配置中禁用 Comments 处理,如下所示:
|
如果您在项目中使用 Lombok,则需要确保其注释处理器在 .
要使用 Maven 执行此操作,您可以使用 Maven 编译器插件的属性以正确的顺序列出 Annotation 处理器。
如果您未使用此属性,并且 Comments 处理器由 Classpath 上可用的依赖项选取,请确保在依赖项之前定义依赖项。 |
自动元数据生成
处理器会选取用 @ConfigurationProperties
注释的类和方法。
不支持使用 @ConfigurationProperties 进行元注释的自定义注释。 |
如果类具有单个参数化构造函数,则每个构造函数参数将创建一个属性,除非构造函数使用 @Autowired
进行批注。
如果类具有使用 @ConstructorBinding
显式批注的构造函数,则会为该构造函数的每个构造函数参数创建一个属性。
否则,将通过存在标准 getter 和 setter 来发现属性,并对 collection 和 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
}
这暴露了三个属性,其中 has no default 和 defaults to 分别是 和。
字段上的 Javadoc 用于填充属性。例如,的描述是 “IP address to listen to.”。my.server.name
my.server.ip
my.server.port
"127.0.0.1"
9797
description
my.server.ip
您应该只使用带有 Javadoc 字段@ConfigurationProperties 纯文本,因为它们在添加到 JSON 之前不会进行处理。 |
如果将 @ConfigurationProperties
与记录类一起使用,则应通过类级 Javadoc 标记提供记录组件的描述(记录类中没有显式的实例字段来放置常规字段级 Javadocs)。@param
注释处理器应用许多启发式方法从源模型中提取默认值。
默认值必须静态提供。特别是,不要引用在另一个类中定义的常量。
此外,注释处理器无法自动检测 s 和 s 的默认值。Enum
Collections
对于无法检测到默认值的情况,应提供手动元数据。 请考虑以下示例:
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"
}
]}
只有 of the property 需要记录现有属性的其他元数据。name |
嵌套属性
注释处理器会自动将内部类视为嵌套属性。
我们可以为它创建一个子命名空间,而不是在命名空间的根目录下记录 and。
请考虑更新后的示例:ip
port
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;
}
// @fold:off // getters/setters ...
}
}
前面的示例生成 、 和 属性的元数据信息。
您可以在字段上使用 @NestedConfigurationProperty
注释来指示应将常规(非内部)类视为嵌套类。my.server.name
my.server.host.ip
my.server.host.port
这对集合和映射没有影响,因为这些类型是自动识别的,并且会为每个类型生成一个元数据属性。 |
添加其他元数据
Spring Boot 的配置文件处理非常灵活,并且通常存在未绑定到 @ConfigurationProperties
bean 的属性。
您可能还需要调整现有键的某些属性。
为了支持此类情况并让您提供自定义“提示”,注释处理器会自动将项目合并到主元数据文件中。META-INF/additional-spring-configuration-metadata.json
如果引用已自动检测到的属性,则描述、默认值和弃用信息(如果指定)将被覆盖。 如果在当前模块中未标识手动属性声明,则会将其添加为新属性。
文件的格式与常规 .
其他属性文件是可选的。
如果您没有任何其他属性,请不要添加该文件。additional-spring-configuration-metadata.json
spring-configuration-metadata.json