Generating Your Own Metadata by Using the Annotation Processor

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

You can easily generate your own configuration metadata file from items annotated with @ConfigurationProperties by using the spring-boot-configuration-processor jar. The jar includes a Java annotation processor which is invoked as your project is compiled.

Configuring the Annotation Processor

要使用处理器,请包含对 spring-boot-configuration-processor 的依赖关系。

To use the processor, include a dependency on spring-boot-configuration-processor.

使用 Maven 时,依赖项应声明为可选的,如下例所示:

With Maven the dependency should be declared as optional, as shown in the following example:

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

对于 Gradle,应在 `annotationProcessor`配置中声明依赖项,如下面的示例所示:

With Gradle, the dependency should be declared in the annotationProcessor configuration, as shown in the following example:

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

如果你正在使用 additional-spring-configuration-metadata.json 文件,则应将 compileJava 任务配置为依赖于 processResources 任务,如下例所示:

If you are using an additional-spring-configuration-metadata.json file, the compileJava task should be configured to depend on the processResources task, as shown in the following example:

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

此依赖关系可确保在注释处理器在编译期间运行时提供其他元数据。

This dependency ensures that the additional metadata is available when the annotation processor runs during compilation.

如果你在项目中使用 AspectJ,你需要确保注释处理器只运行一次。有多种方法可以做到这一点。使用 Maven 时,你可以显式配置 maven-apt-plugin 并仅向此处添加注释处理器的依赖项。你还可以让 AspectJ 插件运行所有处理并禁用 maven-compiler-plugin 配置中的注释处理,如下所示:

If you are using AspectJ in your project, you need to make sure that the annotation processor runs only once. There are several ways to do this. With Maven, you can configure the maven-apt-plugin explicitly and add the dependency to the annotation processor only there. You could also let the AspectJ plugin run all the processing and disable annotation processing in the maven-compiler-plugin configuration, as follows:

<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 依赖项之前定义。

If you are using Lombok in your project, you need to make sure that its annotation processor runs before spring-boot-configuration-processor. To do so with Maven, you can list the annotation processors in the right order using the annotationProcessors attribute of the Maven compiler plugin. If you are not using this attribute, and annotation processors are picked up by the dependencies available on the classpath, make sure that the lombok dependency is defined before the spring-boot-configuration-processor dependency.

Automatic Metadata Generation

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

The processor picks up both classes and methods that are annotated with @ConfigurationProperties.

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

If the class has a single parameterized constructor, one property is created per constructor parameter, unless the constructor is annotated with @Autowired. If the class has a constructor explicitly annotated with @ConstructorBinding, one property is created per constructor parameter for that constructor. Otherwise, properties are discovered through the presence of standard getters and setters with special handling for collection and map types (that is detected even if only a getter is present). The annotation processor also supports the use of the @Data, @Value, @Getter, and @Setter lombok annotations.

请考虑以下示例:

Consider the following example:

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

This exposes three properties where my.server.name has no default and my.server.ip and my.server.port defaults to "127.0.0.1" and 9797 respectively. The Javadoc on fields is used to populate the description attribute. For instance, the description of my.server.ip is "IP address to listen to.".

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

You should only use plain text with @ConfigurationProperties field Javadoc, since they are not processed before being added to the JSON.

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

The annotation processor applies a number of heuristics to extract the default value from the source model. Default values have to be provided statically. In particular, do not refer to a constant defined in another class. Also, the annotation processor cannot auto-detect default values for `Enum`s and `Collections`s.

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

For cases where the default value could not be detected, manual metadata should be provided. Consider the following example:

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

In order to document default values for properties in the class above, you could add the following content to the manual metadata of the module:

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

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

Only the name of the property is required to document additional metadata for existing properties.

Nested Properties

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

The annotation processor automatically considers inner classes as nested properties. Rather than documenting the ip and port at the root of the namespace, we could create a sub-namespace for it. Consider the updated example:

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

The preceding example produces metadata information for my.server.name, my.server.host.ip, and my.server.host.port properties. You can use the @NestedConfigurationProperty annotation on a field to indicate that a regular (non-inner) class should be treated as if it were nested.

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

This has no effect on collections and maps, as those types are automatically identified, and a single metadata property is generated for each of them.

Adding Additional Metadata

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

Spring Boot’s configuration file handling is quite flexible, and it is often the case that properties may exist that are not bound to a @ConfigurationProperties bean. You may also need to tune some attributes of an existing key. To support such cases and let you provide custom "hints", the annotation processor automatically merges items from META-INF/additional-spring-configuration-metadata.json into the main metadata file.

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

If you refer to a property that has been detected automatically, the description, default value, and deprecation information are overridden, if specified. If the manual property declaration is not identified in the current module, it is added as a new property.

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

The format of the additional-spring-configuration-metadata.json file is exactly the same as the regular spring-configuration-metadata.json. The additional properties file is optional. If you do not have any additional properties, do not add the file.