您可以使用 jar 轻松地从带有注释的项目生成自己的配置元数据文件。 该 jar 包含一个 Java 注释处理器,该处理器在编译项目时被调用。@ConfigurationPropertiesspring-boot-configuration-processorSpring中文文档

配置注释处理器

若要使用处理器,请包含对 的依赖项。spring-boot-configuration-processorSpring中文文档

使用 Maven 时,应将依赖项声明为可选,如以下示例所示:Spring中文文档

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

使用 Gradle 时,应在配置中声明依赖项,如以下示例所示:annotationProcessorSpring中文文档

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

如果使用的是文件,则应将任务配置为依赖于任务,如以下示例所示:additional-spring-configuration-metadata.jsoncompileJavaprocessResourcesSpring中文文档

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

此依赖关系可确保在编译期间注释处理器运行时,其他元数据可用。Spring中文文档

如果在项目中使用 AspectJ,则需要确保注释处理器仅运行一次。 有几种方法可以做到这一点。 使用 Maven,您可以显式配置并将依赖项添加到注释处理器中。 您也可以让 AspectJ 插件在配置中运行所有处理并禁用注释处理,如下所示:maven-apt-pluginmaven-compiler-pluginSpring中文文档

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

如果您在项目中使用 Lombok,则需要确保其注释处理器在 之前运行。 要使用 Maven 执行此操作,您可以使用 Maven 编译器插件的属性按正确的顺序列出注释处理器。 如果未使用此属性,并且批注处理器由类路径上可用的依赖项选取,请确保在依赖项之前定义依赖项。spring-boot-configuration-processorannotationProcessorslombokspring-boot-configuration-processorSpring中文文档

如果在项目中使用 AspectJ,则需要确保注释处理器仅运行一次。 有几种方法可以做到这一点。 使用 Maven,您可以显式配置并将依赖项添加到注释处理器中。 您也可以让 AspectJ 插件在配置中运行所有处理并禁用注释处理,如下所示:maven-apt-pluginmaven-compiler-pluginSpring中文文档

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

如果您在项目中使用 Lombok,则需要确保其注释处理器在 之前运行。 要使用 Maven 执行此操作,您可以使用 Maven 编译器插件的属性按正确的顺序列出注释处理器。 如果未使用此属性,并且批注处理器由类路径上可用的依赖项选取,请确保在依赖项之前定义依赖项。spring-boot-configuration-processorannotationProcessorslombokspring-boot-configuration-processorSpring中文文档

自动元数据生成

处理器选取用 .@ConfigurationPropertiesSpring中文文档

如果类具有单个参数化构造函数,则每个构造函数参数创建一个属性,除非构造函数使用 . 如果类具有显式批注的构造函数,则为该构造函数的每个构造函数参数创建一个属性。 否则,将通过存在对集合和映射类型进行特殊处理的标准 getter 和 setter 来发现属性(即使仅存在 getter 也会检测到)。 注释处理器还支持使用 、 、 和 龙目岛 注释。@Autowired@ConstructorBinding@Data@Value@Getter@SetterSpring中文文档

请看以下示例:Spring中文文档

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

}

这将公开三个属性,其中没有默认值,并且分别默认为 和 。 字段上的 Javadoc 用于填充属性。例如,的描述是“要收听的 IP 地址”。my.server.namemy.server.ipmy.server.port"127.0.0.1"9797descriptionmy.server.ipSpring中文文档

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

如果与记录类一起使用,则应通过类级 Javadoc 标记提供记录组件的描述(记录类中没有显式实例字段来放置常规字段级 Javadoc)。@ConfigurationProperties@paramSpring中文文档

注释处理器应用许多启发式方法从源模型中提取默认值。 默认值必须静态提供。特别是,不要引用在另一个类中定义的常量。 此外,注释处理器无法自动检测 s 和 s 的默认值。EnumCollectionsSpring中文文档

对于无法检测到默认值的情况,应提供手动元数据。 请看以下示例:Spring中文文档

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

	}

}

为了记录上述类中属性的默认值,可以将以下内容添加到模块的手动元数据中:Spring中文文档

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

嵌套属性

注释处理器会自动将内部类视为嵌套属性。 我们可以为它创建一个子命名空间,而不是在命名空间的根目录下记录 and。 请考虑更新后的示例:ipportSpring中文文档

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 ...

	}

}

前面的示例生成 、 和 属性的元数据信息。 可以使用字段上的注释来指示应将常规(非内部)类视为嵌套类。my.server.namemy.server.host.ipmy.server.host.port@NestedConfigurationPropertySpring中文文档

这对集合和映射没有影响,因为这些类型是自动识别的,并且会为每个类型生成一个元数据属性。
您应该只使用带有字段 Javadoc 的纯文本,因为它们在添加到 JSON 之前不会被处理。@ConfigurationProperties
只有属性需要记录现有属性的其他元数据。name
这对集合和映射没有影响,因为这些类型是自动识别的,并且会为每个类型生成一个元数据属性。

添加其他元数据

Spring Boot 的配置文件处理非常灵活,通常情况下,可能存在未绑定到 Bean 的属性。 您可能还需要调整现有密钥的某些属性。 为了支持这种情况并允许您提供自定义“提示”,注释处理器会自动将项目合并到主元数据文件中。@ConfigurationPropertiesMETA-INF/additional-spring-configuration-metadata.jsonSpring中文文档

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

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