144 lines
6.7 KiB
Plaintext
144 lines
6.7 KiB
Plaintext
[[configuration-metadata.annotation-processor]]
|
|
== Generating Your Own Metadata by Using the Annotation Processor
|
|
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.
|
|
|
|
|
|
|
|
[[configuration-metadata.annotation-processor.configuring]]
|
|
=== Configuring the Annotation Processor
|
|
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:
|
|
|
|
[source,xml,indent=0,subs="verbatim"]
|
|
----
|
|
<dependency>
|
|
<groupId>org.springframework.boot</groupId>
|
|
<artifactId>spring-boot-configuration-processor</artifactId>
|
|
<optional>true</optional>
|
|
</dependency>
|
|
----
|
|
|
|
With Gradle, the dependency should be declared in the `annotationProcessor` configuration, as shown in the following example:
|
|
|
|
[source,gradle,indent=0,subs="verbatim"]
|
|
----
|
|
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:
|
|
|
|
[source,gradle,indent=0,subs="verbatim"]
|
|
----
|
|
compileJava.inputs.files(processResources)
|
|
----
|
|
|
|
This dependency ensures that the additional metadata is available when the annotation processor runs during compilation.
|
|
|
|
[NOTE]
|
|
====
|
|
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:
|
|
|
|
[source,xml,indent=0,subs="verbatim"]
|
|
----
|
|
<plugin>
|
|
<groupId>org.apache.maven.plugins</groupId>
|
|
<artifactId>maven-compiler-plugin</artifactId>
|
|
<configuration>
|
|
<proc>none</proc>
|
|
</configuration>
|
|
</plugin>
|
|
----
|
|
====
|
|
|
|
|
|
|
|
[[configuration-metadata.annotation-processor.automatic-metadata-generation]]
|
|
=== Automatic Metadata Generation
|
|
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`, `@Value`, `@Getter`, and `@Setter` lombok annotations.
|
|
|
|
Consider the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim"]
|
|
----
|
|
include::{docs-java}/configurationmetadata/annotationprocessor/automaticmetadatageneration/MyServerProperties.java[]
|
|
----
|
|
|
|
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.".
|
|
|
|
NOTE: 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, <<configuration-metadata#configuration-metadata.annotation-processor.adding-additional-metadata,manual metadata>> should be provided.
|
|
Consider the following example:
|
|
|
|
[source,java,indent=0,subs="verbatim"]
|
|
----
|
|
include::{docs-java}/configurationmetadata/annotationprocessor/automaticmetadatageneration/MyMessagingProperties.java[]
|
|
----
|
|
|
|
In order to document default values for properties in the class above, you could add the following content to <<configuration-metadata#configuration-metadata.annotation-processor.adding-additional-metadata,the manual metadata of the module>>:
|
|
|
|
[source,json,indent=0,subs="verbatim"]
|
|
----
|
|
{"properties": [
|
|
{
|
|
"name": "my.messaging.addresses",
|
|
"defaultValue": ["a", "b"]
|
|
},
|
|
{
|
|
"name": "my.messaging.container-type",
|
|
"defaultValue": "simple"
|
|
}
|
|
]}
|
|
----
|
|
|
|
NOTE: Only the `name` of the property is required to document additional metadata for existing properties.
|
|
|
|
|
|
|
|
[[configuration-metadata.annotation-processor.automatic-metadata-generation.nested-properties]]
|
|
==== Nested 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:
|
|
|
|
[source,java,indent=0,subs="verbatim"]
|
|
----
|
|
include::{docs-java}/configurationmetadata/annotationprocessor/automaticmetadatageneration/nestedproperties/MyServerProperties.java[]
|
|
----
|
|
|
|
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.
|
|
|
|
TIP: 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.
|
|
|
|
|
|
|
|
[[configuration-metadata.annotation-processor.adding-additional-metadata]]
|
|
=== Adding Additional Metadata
|
|
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.
|