purpose
The auxiliary function of configuration automatic prompt can make configuration write faster and accuracy greatly improved.
The Springboot JAR contains metadata files that provide details of all supported configuration properties. The purpose of the file is to allow IDE developers to provide context assistance and code completion when users use application.properties or application.yml files.
Most metadata files are generated automatically at compile time by processing all items annotated with @ConfigurationProperties. You can also write some metadata manually.
version
Refer to the SpringBoot 2.2.0.release documentation
file
Meta-inf /spring-configuration-metadata.json (automatically generated) or meta-INF/Additional spring-configuration-metadata.json (manually added)
In actual combat
<! <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>Copy the code
@Configuration @ConfigurationProperties(prefix = "file.upload") public class FileUploadConfig { /** Maximum number of bytes per file */ private String maxSize = "1024M"; /** Disallowed file suffixes */ private String rejectSuffix; Getter /setter}; // Use getter/setter}; // Use getter/setter}Copy the code
@configuration@configurationProperties ("map.test") public class MapTestConfig {/** private map <String, Object> data; Getter /setter}; // Use getter/setter}; // Use getter/setter}Copy the code
Chinese annotations will be garbled. Where Chinese annotations are deliberately used above, the corresponding description will be specified in the following file to see whether they will be overwritten.
additional-spring-configuration-metadata.json
{
"properties": [
{
"name": "file.upload.reject-suffix",
"type": "java.lang.String",
"defaultValue": "exe,jar",
"description": "The file suffix is not allowed.",
"sourceType": "com.lw.metadata.config.FileUploadConfig"
},
{
"name": "map.test.data",
"type": "java.util.Map",
"description": "Tips for testing Map type data.",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"hints": [
{
"name": "map.test.data.keys",
"values": [
{
"value": "name",
"description": "The name of the person."
},
{
"value": "sex",
"description": "The sex of the person."
}
]
}
]
}Copy the code
Json = spring-configuration-metadata.json = spring-configuration-metadata.json = spring-configuration-metadata.json = spring-configuration-metadata.json = spring-configuration-metadata.json
{
"groups": [
{
"name": "file.upload",
"type": "com.lw.metadata.config.FileUploadConfig",
"sourceType": "com.lw.metadata.config.FileUploadConfig"
},
{
"name": "map.test",
"type": "com.lw.metadata.config.MapTestConfig",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"properties": [
{
"name": "file.upload.max-size",
"type": "java.lang.String",
"description": "Maximum number of bytes per file",
"sourceType": "com.lw.metadata.config.FileUploadConfig",
"defaultValue": "1024M"
},
{
"name": "file.upload.reject-suffix",
"type": "java.lang.String",
"description": "The file suffix is not allowed.",
"sourceType": "com.lw.metadata.config.FileUploadConfig",
"defaultValue": "exe,jar"
},
{
"name": "map.test.data",
"type": "java.util.Map<java.lang.String,java.lang.Object>",
"description": "Tips for testing Map type data.",
"sourceType": "com.lw.metadata.config.MapTestConfig"
}
],
"hints": [
{
"name": "map.test.data.keys",
"values": [
{
"value": "name",
"description": "The name of the person."
},
{
"value": "sex",
"description": "The sex of the person."
}
]
}
]
}Copy the code
The effect
The following phenomena can be seen:
- Default values in the code are automatically generated in the prompt file, such as FileUploadConfig#maxSize
- Comments in the code are automatically generated in a prompt file, such as FileUploadConfig#maxSize
- The information in the additional-spring-configuration-metadata.json file overwrites the automatically generated property. If the automatically generated property does not contain this property, it is automatically added.
Write the prompt file manually
The sample
{
"groups": [
{
"name": "server",
"type": "org.springframework.boot.autoconfigure.web.ServerProperties",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate",
"type": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties",
"sourceMethod": "getHibernate()"
}
],
"properties": [
{
"name": "server.port",
"type": "java.lang.Integer",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.address",
"type": "java.net.InetAddress",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "spring.jpa.hibernate.ddl-auto",
"type": "java.lang.String",
"description": "DDL mode. This is actually a shortcut for the \"hibernate.hbm2ddl.auto\" property.",
"sourceType": "org.springframework.boot.autoconfigure.orm.jpa.JpaProperties$Hibernate"
}
],
"hints": [
{
"name": "spring.jpa.hibernate.ddl-auto",
"values": [
{
"value": "none",
"description": "Disable DDL handling."
},
{
"value": "validate",
"description": "Validate the schema, make no changes to the database."
},
{
"value": "update",
"description": "Update the schema if necessary."
},
{
"value": "create",
"description": "Create the schema and destroy previous data."
},
{
"value": "create-drop",
"description": "Create and then destroy the schema at the end of the session."
}
]
}
]
}Copy the code
groups
Grouping, grouping configuration classes. You can group by file, that is, put all attributes of the same profile in the same group
attribute |
type |
Whether must | use |
---|---|---|---|
name |
String | Y |
The full name of the group |
type |
String | N |
Class names of grouped data types (e.g., full class names with @ConfigurationProperties annotations, method return types with @bean annotations) |
description |
String | N |
Grouping ofbriefDescription. |
sourceType |
String | N |
Provide the name of the class from which the grouping is derived. |
sourceMethod | String | N |
Provides methods for grouping, including parentheses and parameter types. |
properties
Prompt subject, must
attribute |
type |
Whether must | use |
---|---|---|---|
name |
String |
Y |
The full name of the property. The namesLowercase period separatorFormat, such as:server.address |
type |
String |
N |
The full signature of the property data type (e.g.java.lang.String ) or a full generic type (e.g.java.util.Map ). This property prompts the user for a value type. Native types use their wrapper types here (e.g.boolean usejava.lang.Boolean ). |
description |
String |
N |
Grouping ofbriefDescription. |
sourceType |
String |
N |
Provide the name of the class from which the grouping is derived. |
defaultValue | Object |
N |
The default value. Used when the property is specified. |
deprecation |
Deprecation | N |
Specifies whether the attribute is deprecated. |
The deprecation attribute is as follows:
attribute |
type |
Whether must | use |
---|---|---|---|
level |
String | N |
Deprecation level, which can bewarning (Default value) orerror .warning : Attributes should still be available;error The: attribute is not guaranteed to be used |
reason |
String | N |
Short reasons for attribute deprecation. |
replacement | String | N |
Replaces the new property full name for this deprecated property.Can be null |
Note: Prior to Spring Boot version 1.3, deprecated was deprecated using Boolean.
The following example from official documentation shows how to handle this scenario:
`java
@ConfigurationProperties(“app.acme”)
public class AcmeProperties {
private String name;
public String getName() { … }
public void setName(String name) { … }
@DeprecatedConfigurationProperty(replacement = “app.acme.name”)
@Deprecated
public String getTarget() {
return getName();
}
@Deprecated
public void setTarget(String target) {
setName(target);
}
}
`
Once the getTarget and setTarget methods are removed from the public API, the automatic deprecation prompts in the metadata also disappear. If you want to keep hints, adding manual metadata with the error deprecation level ensures that users are still aware of the property. This is particularly useful when providing alternatives.
hints
Auxiliary hints, not required
attribute |
type |
Whether must | use |
---|---|---|---|
name |
String |
Y |
Indicates the full name of the associated property. The name isLowercase period separatorFormat (e.g.spring.mvc.servlet.path ), if the attribute is associated with a map type (e.g.system.contexts ), indicating that the map can be associated with the key (system.contexts.keys ) or value (system.contexts.values ). |
values |
ValueHint[] |
N |
Set of valid values. (Detailed in the table below) |
providers | ValueProvider[] | N |
Collection of providers. (Detailed in the table below) |
Values attributes are as follows:
attribute |
type |
Whether must | use |
---|---|---|---|
value |
Object | Y |
Prompt for valid values for reference elements. If the property is an array, value and description can also be arrays. |
description | String | N |
Value Indicates the short description of the value |
ValueHint
Map types are supported as follows:
@ConfigurationProperties("sample")
public class SampleProperties {
private Map<String,Integer> contexts;
// getters and setters
}Copy the code
{"hints": [
{
"name": "sample.contexts.keys",
"values": [
{
"value": "sample1"
},
{
"value": "sample2"
}
]
}
]}Copy the code
The prompt is for each pair of key-values in the Map.
The. Keys and. Values prefixes must be associated with keys and values of the Map, respectively.
Providers attributes are as follows:
attribute |
type |
Whether must | use |
---|---|---|---|
name |
String |
N |
The name of the provider used to provide additional content assistance for the element referenced by the prompt. |
parameters | JSON object | N |
Any other parameters supported by the provider (see the documentation for the provider for more information). |
ValueProvider
* It is recommended to skip *
The following table summarizes the supported providers list:
attribute |
describe |
---|---|
any |
Any added value is allowed. |
class-reference |
Automatically complete the classes available in the project. Base class constraints, usually specified by the target parameter. |
handle-as |
Handle the property as if it were defined by a type defined by the required target parameter. |
logger-name |
Automatically complete valid logger names and logger groups. Typically, the package and class names available in the current project can be completed automatically or groups can be defined. |
spring-bean-reference | Automatically complete the bean names available in the current project. The base class constraint, usually specified by the target parameter. |
spring-profile-name |
The name of the Spring configuration file available in the autocomplete project. |
any
All values that match the attribute type.
{"hints": [
{
"name": "system.state",
"values": [
{
"value": "on"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}Copy the code
class-reference
Provide the following parameters:
parameter |
type |
The default value | describe |
---|---|---|---|
target |
String (Class) | There is no |
The fully qualified class name of the class assigned to the value. Usually used to filter non-candidate classes. |
concrete | boolean |
true |
Specifies whether only concrete classes are considered valid candidates. |
{"hints": [
{
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "javax.servlet.http.HttpServlet"
}
}
]
}
]}Copy the code
handle-as
Allows you to replace the type of a property with a more advanced type.
This usually happens when the property has type java.lang.String, because you don’t want the configuration class to depend on classes that aren’t on the classpath.
parameter |
type |
The default value | describe |
|
---|---|---|---|---|
target | String (Class) | There is no |
Y |
The fully qualified name of the type considered for the property. |
The available values are as follows:
- any
java.lang.Enum
: lists the possible values for the attribute. java.nio.charset.Charset
: Supports automatic completion of character set/encoding values (e.gutf-8
)java.util.Locale
: Automatically completes locale Settings (e.g.en_US
)org.springframework.util.MimeType
: Supports auto-complete content-type values (e.g.text/plain
)org.springframework.core.io.Resource
: Supports automatic spring resource abstraction to reference files on file systems or classpath (e.g.classpath:/sample.properties
)
Note: If you want to supply multiple values, use Collection or array types
{"hints": [
{
"name": "spring.liquibase.change-log",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]}Copy the code
logger-name
Logger-name The provider automatically completes the valid logger name and logger group. Typically, the package and class names available in the current project can be done automatically. If a group is enabled (the default) and a custom logger group is identified in the configuration, auto-completion for that group should be provided.
The following parameters are supported:
parameter |
type |
The default value | describe |
---|---|---|---|
group | boolean | true |
Specifies whether known groups should be considered. |
Because logger names can be arbitrary, this provider should allow any value, but it can highlight valid package and class names that are not available in the project’s classpath.
Here is the logging.level property. Keys is logger name, values is associated with standard log levels or custom levels,
{"hints": [
{
"name": "logging.level.keys",
"values": [
{
"value": "root",
"description": "Root logger used to assign the default logging level."
},
{
"value": "sql",
"description": "SQL logging group including Hibernate SQL logger."
},
{
"value": "web",
"description": "Web logging group including codecs."
}
],
"providers": [
{
"name": "logger-name"
}
]
},
{
"name": "logging.level.values",
"values": [
{
"value": "trace"
},
{
"value": "debug"
},
{
"value": "info"
},
{
"value": "warn"
},
{
"value": "error"
},
{
"value": "fatal"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}Copy the code
spring-bean-reference
This provider automatically completes the beans defined in the configuration of the current project. The following parameters are supported:
{"hints": [
{
"name": "spring.jmx.server",
"providers": [
{
"name": "spring-bean-reference",
"parameters": {
"target": "javax.management.MBeanServer"
}
}
]
}
]}Copy the code
spring-profile-name
This provider automatically completes the Spring configuration file defined in the configuration of the current project.
The following example represents the name of the profile that can be enabled by the spring.profiles.active property.
{"hints": [
{
"name": "spring.profiles.active",
"providers": [
{
"name": "spring-profile-name"
}
]
}
]}Copy the code
Repeatable metadata items
Objects with the same “property” and “group” names can appear more than once in a metadata file. For example, two separate classes can be bound to the same prefix, each with potentially overlapping attribute names. While the same name that appears multiple times in metadata should not be common, consumers of metadata should take care to ensure that they support it.
Automatically generate prompt files
Using the Spring-boot-configuration-Processor JAR, you can easily generate your own configuration metadata files from classes annotated with @ConfigurationProperties. The JAR contains a Java annotation handler that is called when the project is compiled. To use this processor, you need to introduce the spring-boot-configuration-processor dependency.
`xml
org.springframework.boot
spring-boot-configuration-processor
true
`
The handler gets classes and methods annotated with @ConfigurationProperties. The Javadoc that configures the field values in the class is used to populate the Description attribute.
Note: Only simple text should be used with the @ConfigurationProperties field Javadoc, because they are not processed before they are added to JSON.
If the class has a “at least one argument” constructor, create a property for each constructor argument. Otherwise, properties are discovered through standard getters and setters that perform special treatment on collection types (even if only the getter exists).
The annotation processor also supports Lombok annotations using @data, @getter, and @setter.
The annotation processor cannot automatically detect the default values for Enum and Collections. Manual metadata should be provided in cases where a collection or enumeration property has a non-empty default value.
@ConfigurationProperties(prefix="acme.messaging")
public class MessagingProperties {
private List<String> addresses = new ArrayList<>(Arrays.asList("a", "b")) ;
private ContainerType = ContainerType.SIMPLE;
// ... getter and setters
public enum ContainerType {
SIMPLE,
DIRECT
}
}Copy the code
To indicate the default values for the above attributes, the following metadata should be manually added:
{"properties": [
{
"name": "acme.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "acme.messaging.container-type",
"defaultValue": "simple"
}
]}Copy the code
Note: If you are using AspectJ in your project, you need to ensure that the annotation processor runs only once. When using Maven, you can explicitly configure the Maven-apt-plugin plug-in and add dependencies to the annotation processor only there. You can also have the AspectJ plug-in run on all processing and disable annotation processing in the Configuration of the Maven-Compiler-plugin, as follows:
`java
org.apache.maven.plugins
maven-compiler-plugin
none
`
Binding properties
Annotation handlers automatically treat inner classes as nested properties.
@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
}
}Copy the code
The above example generates metadata information for the server.name, server.host. IP, and server.host.port properties. Can be used on field @ NestedconfigurationProperty annotations to indicate that the conventional (internal) class should be regarded as nested classes.
Note: This has no effect on collections and maps because these types are automatically identified and a metadata attribute is generated for each type.
Add additional metadata
Spring Boot’s configuration file handling is very flexible, and in general there may be properties that are not bound to the @ConfigurationProperties bean. You may also need to adjust some properties of your existing key, and to support this and allow you to provide custom “hints,” The annotation processor automatically merges the prompts in meta-INF/Additional -spring-configuration-metadata.json into the main metadata file (spring-configuration-metadata.json).
If a reference is made to an automatically detected property, the description, default value, and deprecation information (if specified) are overridden. If the declaration in the manual property 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 the same as that of the spring-configuration-metadata.json file. The attached properties file is optional. If you don’t have any other properties, don’t add the file.
The resources
Yi Fei Xi (focus on in-depth learning of Java domain knowledge, from source code to principle, systematic and orderly learning)