Generating Your Own Metadata by Using the Annotation Processor

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

Configuring the Annotation Processor

要使用处理器,请包含对 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 属性按照正确的顺序列出注释处理器。如果你不使用此属性,并且注释处理器被类路径上可用的依赖项所选取,请确保 lombok 依赖项在 spring-boot-configuration-processor 依赖项之前定义。

Automatic Metadata Generation

该处理器选取同时使用 @ConfigurationProperties 做注释的类和方法。

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

请考虑以下示例:

这公开三个属性,其中 my.server.name 没有默认值,my.server.ipmy.server.port 分别默认为 "127.0.0.1"9797。字段上的 Javadoc 用于填充 description 属性。例如,my.server.ip 的描述是“要监听的 IP 地址”。

您应该只将纯文本与 `@ConfigurationProperties`字段 Javadoc 一起使用,因为在将它们添加到 JSON 之前不会对其进行处理。

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

对于无法检测到默认值的情况,应提供 manual metadata。考虑以下示例:

要记录上述类中属性的默认值,你可以在 the manual metadata of the module 中添加以下内容:

{"properties": [
	{
		"name": "my.messaging.addresses",
		"defaultValue": ["a", "b"]
	},
	{
		"name": "my.messaging.container-type",
		"defaultValue": "simple"
	}
]}

只需要属性的 name 就能记录现有属性的其他元数据。

Nested Properties

注释处理器会自动将内部类视为嵌套属性。与其在命名空间的根级记录 ipport,我们也可以为其创建一个子命名空间。考虑更新后的示例:

上述示例会生成 my.server.namemy.server.host.ipmy.server.host.port 属性的元数据信息。你可以在字段上使用 @NestedConfigurationProperty 注释,表示一个常规(非内部)类应该被视为嵌套类。

这不会对集合和映射产生影响,因为这些类型会自动识别,而且针对其中的每一个,都会生成一个元数据属性。

Adding Additional Metadata

Spring Boot 的配置文件处理非常灵活,而且通常会出现未绑定到 @ConfigurationProperties Bean 的属性。你可能还需要调整现有键的某些属性。为了支持此类情况并允许你提供自定义“提示”,注释处理器会自动将 META-INF/additional-spring-configuration-metadata.json 中的项目合并到主元数据文件中。

如果你引用的属性已自动检测到,那么如果指定了说明、默认值和弃用信息,则会覆盖这些内容。如果在当前模块中未识别手动属性声明,则将之添加为新属性。

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