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.
To use the processor, include a dependency on spring-boot-configuration-processor
.
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>
If you have defined @ConfigurationProperties
in your application, make sure to configure the spring-boot-maven-plugin
to prevent the repackage
goal from adding the dependency into the fat jar:
<project>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
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"
}
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:
compileJava.inputs.files(processResources)
This dependency ensures that the additional metadata is available when the annotation processor runs during compilation.
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>
The processor picks up both classes and methods that are annotated with @ConfigurationProperties
.
If the class is also annotated with @ConstructorBinding
, a single constructor is expected and one property is created per constructor parameter. 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
, @Getter
, and @Setter
lombok annotations.
Consider the following example:
@ConfigurationProperties(prefix="server")
public class ServerProperties {
/**
* 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;
// ... getter and setters
}
This exposes three properties where server.name
has no default and server.ip
and 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 server.ip
is "IP address to listen to.".
You should only use plain text with @ConfigurationProperties
field Javadoc, since they are not processed before being added to the JSON.
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.
For cases where the default value could not be detected, manual metadata should be provided. Consider the following example:
@ConfigurationProperties(prefix = "acme.messaging")
public class MessagingProperties {
private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b"));
private ContainerType containerType = ContainerType.SIMPLE;
// ... getter and setters
public enum ContainerType {
SIMPLE,
DIRECT
}
}
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": "acme.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "acme.messaging.container-type",
"defaultValue": "simple"
}
]}
Only the name
of the property is required to document additional metadata for existing properties.
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:
@ConfigurationProperties(prefix="server")
public class ServerProperties {
private String name;
private Host host;
// ... getter and setters
public static class Host {
private String ip;
private int port;
// ... getter and setters
}
}
The preceding example produces metadata information for server.name
, server.host.ip
, and 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.
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.
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.
原网址: 访问
创建于: 2023-07-17 15:02:55
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
最新评论