目的
配置自動提示的輔助功能可以讓配置寫起來更快,準確率大大提高性雄。
springboot jar 包含提供所有支持的配置屬性細節(jié)的元數(shù)據(jù)文件留拾。文件的目的是為了讓 IDE 開發(fā)者在用戶使用
application.properties
或application.yml
文件時提供上下文幫助和代碼補全。
大多數(shù)元數(shù)據(jù)文件是在編譯時通過處理用@ConfigurationProperties
注釋的所有項自動生成的泞辐。也可以手動編寫部分元數(shù)據(jù)笔横。
版本
參考 SpringBoot
2.2.0.RELEASE
文檔
文件
jar包中的 META-INF/spring-configuration-metadata.json
(自動生成)或 META-INF/additional-spring-configuration-metadata.json
(手動添加)
實戰(zhàn)
<!-- 引入相關依賴 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@Configuration
@ConfigurationProperties(prefix = "file.upload")
public class FileUploadConfig {
/** Maximum number of bytes per file */
private String maxSize = "1024M";
/** 不允許的文件后綴 */
private String rejectSuffix;
//注意:使用的時候必須要有getter/setter,否則不會自動生成該屬性對應的提示
//此處因為篇幅原因省略 getter/setter
}
@Configuration
@ConfigurationProperties("map.test")
public class MapTestConfig {
/** 測試Map類型數(shù)據(jù)的提示 */
private Map<String, Object> data;
//注意:使用的時候必須要有getter/setter咐吼,否則不會自動生成該屬性對應的提示
//此處因為篇幅原因省略 getter/setter
}
中文注釋會亂碼吹缔,以上故意用中文注釋的地方,會在下面文件中指定對應的描述锯茄,看是否會覆蓋厢塘。
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."
}
]
}
]
}
maven compile 之后,生成的 additional-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."
}
]
}
]
}
效果
由此可以看到以下現(xiàn)象:
- 代碼中的默認值會自動生成到提示文件中晚碾,如:FileUploadConfig#maxSize
- 代碼中的注釋會自動生成到提示文件中,如:FileUploadConfig#maxSize
- additional-spring-configuration-metadata.json 文件中存在的提示會覆蓋自動生成的對應屬性牍颈,若自動生成的沒有此屬性則自動增加迄薄。
手動寫提示文件
示例
{
"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."
}
]
}
]
}
groups
分組,將配置類分組煮岁。
可以按照文件來分組讥蔽,即:將同一個配置文件的所有屬性放在同一個組
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
name | String | Y | 分組的完整名稱 |
type | String | N | 分組數(shù)據(jù)類型的類名(如:使用@ConfigurationProperties注釋的完整類名、使用@Bean注釋的方法返回類型) |
description | String | N | 分組的簡短描述画机。 |
sourceType | String | N | 提供分組來源的類名冶伞。 |
sourceMethod | String | N | 提供分組的方法,包含括號和參數(shù)類型步氏。 |
properties
提示主體响禽,必須
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
name | String | Y | 屬性的完整名稱。名稱采用小寫句點分隔格式,如:server.address
|
type | String | N | 屬性數(shù)據(jù)類型的完整簽名(如:java.lang.String )或完整的泛型類型(如:java.util.Map<java.util.String,acme.Myenum> )芋类。此屬性提示用戶輸入值得類型隆嗅。原生類型在此處使用其包裝類型(如:boolean 使用java.lang.Boolean )。 |
description | String | N | 分組的簡短描述侯繁。 |
sourceType | String | N | 提供分組來源的類名胖喳。 |
defaultValue | Object | N | 默認值。當屬性為指定時使用贮竟。 |
deprecation | Deprecation | N | 指定屬性是否已棄用丽焊。 |
deprecation屬性如下:
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
level | String | N | 棄用級別,可以是 warning (默認值) 或 error 咕别。warning :屬性應該仍然可以使用技健;error :屬性不保證可以使用 |
reason | String | N | 屬性棄用的簡短原因。 |
replacement | String | N | 替換此棄用屬性的新屬性全名惰拱。可為空 |
注意:Spring Boot 1.3 版本之前雌贱,是使用 boolean 類型的
deprecated
。
以下示例來源于官方文檔弓颈,展示了如何處理這種場景:
@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); } }
一旦
getTarget
和setTarget
方法從公共 API 中刪除帽芽,元數(shù)據(jù)中的自動棄用提示也會消失删掀。 如果要保留提示翔冀,則添加具有error
棄用級別的手動元數(shù)據(jù)可以確保用戶仍然了解該屬性。在提供替代品時披泪,這樣做特別有用纤子。
hints
輔助提示,非必須
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
name | String | Y | 提示關聯(lián)的屬性的完整名稱款票。名稱是小寫句點分隔格式(如:spring.mvc.servlet.path )控硼,如果屬性關聯(lián)map類型(如:system.contexts ),提示可以關聯(lián)map的鍵(system.contexts.keys )或者值(system.contexts.values )艾少。 |
values | ValueHint[] | N | 有效值集合卡乾。(下表詳述) |
providers | ValueProvider[] | N | 提供者集合。(下表詳述) |
values
屬性如下:
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
value | Object | Y | 提示引用元素的有效值缚够。如果屬性是數(shù)組幔妨,value和description也可以是數(shù)組。 |
description | String | N | value 對應的簡短描述 |
ValueHint
對于Map類型的支持如下:
@ConfigurationProperties("sample")
public class SampleProperties {
private Map<String,Integer> contexts;
// getters and setters
}
{"hints": [
{
"name": "sample.contexts.keys",
"values": [
{
"value": "sample1"
},
{
"value": "sample2"
}
]
}
]}
提示是對Map內(nèi)每一對 key-value 的提示谍椅。
.keys
和.values
前綴必須分別關聯(lián) Map 的 keys 和 values误堡。
providers
屬性如下:
屬性 | 類型 | 是否必須 | 用途 |
---|---|---|---|
name | String | N | 用于為提示所引用的元素提供其他內(nèi)容幫助的 provider 的名稱。 |
parameters | JSON object | N | provider 所支持的任何其他參數(shù)(有關詳細信息雏吭,請查看 provider 的文檔)锁施。 |
ValueProvider
一般用不到,建議跳過
下表總結(jié)了支持的 providers 列表:
屬性 | 描述 |
---|---|
any | 允許提供任何附加值。 |
class-reference | 自動完成項目中可用的類悉抵。通常由目標參數(shù)指定的基類約束肩狂。 |
handle-as | 處理屬性,就像它是由必須的 target 參數(shù)定義的類型定義的一樣姥饰。 |
logger-name | 自動完成有效的記錄器名稱和記錄器組婚温。通常,當前項目中可用的包和類名可以自動完成媳否,也可以定義組栅螟。 |
spring-bean-reference | 自動完成當前項目中可用的bean名稱。通常由 target 參數(shù)指定的基類約束篱竭。 |
spring-profile-name | 自動完成項目中可用的 spring 配置文件名稱力图。 |
any
符合屬性類型的所有值。
{"hints": [
{
"name": "system.state",
"values": [
{
"value": "on"
},
{
"value": "off"
}
],
"providers": [
{
"name": "any"
}
]
}
]}
class-reference
提供以下參數(shù):
參數(shù) | 類型 | 默認值 | 描述 |
---|---|---|---|
target | String(Class) | 無 | 分配給值的類的全限定類名掺逼。通常用于篩選非候選類吃媒。 |
concrete | boolean | true | 指定是否僅將具體類視為有效候選。 |
{"hints": [
{
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "javax.servlet.http.HttpServlet"
}
}
]
}
]}
handle-as
允許您將屬性的類型替換為更高級的類型吕喘。
這通常在屬性具有 java.lang.String
類型時發(fā)生赘那,因為您不希望配置類依賴于不在類路徑上的類。
參數(shù) | 類型 | 默認值 | 描述 | |
---|---|---|---|---|
target | String(Class) | 無 | Y | 為屬性考慮的類型的完全限定名氯质。 |
可用的值如下:
- 任何
java.lang.Enum
: 列出屬性的可能值募舟。 -
java.nio.charset.Charset
: 支持自動完成字符集/編碼值(如utf-8
) -
java.util.Locale
:自動完成區(qū)域設置(如:en_US
) -
org.springframework.util.MimeType
:支持自動完成 content-type 值(如:text/plain
) -
org.springframework.core.io.Resource
: 支持自動完成spring的資源抽象以引用文件系統(tǒng)或類路徑上的文件 (如:classpath:/sample.properties
)
注意:如果要提供多個值,用
Collection
或 數(shù)組類型
{"hints": [
{
"name": "spring.liquibase.change-log",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]}
logger-name
logger-name
provider 自動完成有效的記錄器名稱和記錄器組闻察。 通常拱礁,當前項目中可用的包和類名可以自動完成。 如果組已啟用(默認)辕漂,并且配置中標識了自定義記錄器組呢灶,則應提供該組的自動完成。
支持以下參數(shù):
參數(shù) | 類型 | 默認值 | 描述 |
---|---|---|---|
group | boolean | true | 指定是否應考慮已知組钉嘹。 |
由于記錄器名稱可以是任意名稱鸯乃,此 provider 應允許任何值,但可以突出顯示項目的類路徑中不可用的有效包和類名跋涣。
以下是 logging.level
屬性缨睡。keys 是 logger 名,values 關聯(lián)標準的 log levels 或 自定義的 level仆潮,
{"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"
}
]
}
]}
spring-bean-reference
此 provider 自動完成在當前項目的配置中定義的bean宏蛉。 支持以下參數(shù):
參數(shù) | 類型 | 默認值 | 描述 |
---|---|---|---|
target | String(Class) | 無 | 應該分配給候選對象的bean類的完全限定名。通常用于篩選非候選bean性置。 |
以下示例表示:spring.jmx.server
屬性定義了使用 MBeanServer
{"hints": [
{
"name": "spring.jmx.server",
"providers": [
{
"name": "spring-bean-reference",
"parameters": {
"target": "javax.management.MBeanServer"
}
}
]
}
]}
spring-profile-name
此 provider 自動完成在當前項目的配置中定義的spring配置文件拾并。
以下示例表示:spring.profiles.active
屬性可啟用的配置文件名稱。
{"hints": [
{
"name": "spring.profiles.active",
"providers": [
{
"name": "spring-profile-name"
}
]
}
]}
可重復的元數(shù)據(jù)項
具有相同“property”和“group”名稱的對象可以在元數(shù)據(jù)文件中多次出現(xiàn)。 例如嗅义,可以將兩個單獨的類綁定到同一前綴屏歹,每個類都有可能重疊的屬性名。 雖然多次出現(xiàn)在元數(shù)據(jù)中的相同名稱不應是常見的之碗,但元數(shù)據(jù)的使用者應注意確保他們支持該名稱蝙眶。
自動生成提示文件
通過使用
spring-boot-configuration-processor
jar,您可以從用@ConfigurationProperties
注釋的類中輕松生成自己的配置元數(shù)據(jù)文件褪那。 jar包含一個java注釋處理器幽纷,在編譯項目時調(diào)用它。 用此處理器博敬,需要引入spring-boot-configuration-processor
依賴友浸。<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
處理器獲取用@configurationproperties注釋的類和方法。 配置類中字段值的 javadoc 用于填充 description 屬性偏窝。
注意:僅僅只應將簡單文本與@configurationproperties字段javadoc一起使用收恢,因為在將它們添加到json之前不會對它們進行處理。
如果類有一個“至少一個參數(shù)”的構(gòu)造函數(shù)祭往,則為每個構(gòu)造函數(shù)參數(shù)創(chuàng)建一個屬性伦意。 否則,通過標準getter和setter來發(fā)現(xiàn)屬性硼补,這些getter和setter對集合類型進行了特殊處理(即使只有getter存在驮肉,也會檢測到)。
注解處理器還支持使用@data括勺、@getter和@setter 的 lombok 注解缆八。
注解處理器無法自動檢測
Enum
和Collections
的默認值。在集合或枚舉屬性具有非空默認值的情況下疾捍,應提供手動元數(shù)據(jù)。
@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
}
}
為了提示上述屬性的默認值栏妖,應該手動添加如下元數(shù)據(jù):
{"properties": [
{
"name": "acme.messaging.addresses",
"defaultValue": ["a", "b"]
},
{
"name": "acme.messaging.container-type",
"defaultValue": "simple"
}
]}
注意: 如果在項目中使用 AspectJ乱豆,則需要確保注解處理器只運行一次。 使用 Maven 時吊趾, 可以顯式地配置
maven-apt-plugin
插件宛裕,并僅在那里向注解處理器添加依賴項。 還可以讓 AspectJ 插件運行于所有的處理且在maven-compiler-plugin
的configuration
中禁用注解處理论泛,如下:<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <proc>none</proc> </configuration> </plugin>
綁定屬性
注解處理器自動將內(nèi)部類視為嵌套屬性揩尸。
@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
}
}
上述示例生成
server.name
、server.host.ip
和server.host.port
屬性的元數(shù)據(jù)信息屁奏。 可以在字段上使用@NestedconfigurationProperty 注解來指示應將常規(guī)(非內(nèi)部)類視為嵌套類岩榆。
注意: 這對集合和映射沒有影響,因為這些類型是自動標識的,并且為每個類型生成一個元數(shù)據(jù)屬性勇边。
添加額外的元數(shù)據(jù)
Spring Boot 的配置文件處理非常靈活犹撒,通常情況下,可能存在不綁定到
@ConfigurationProperties
bean的屬性粒褒。 您還可能需要調(diào)整現(xiàn)有key的某些屬性识颊,為了支持這種情況并讓您提供自定義的“提示”,注解處理器會自動將META-INF/additional-spring-configuration-metadata.json
中的提示項合并到主要元數(shù)據(jù)文件(spring-configuration-metadata.json)中**奕坟。如果引用已自動檢測到的屬性祥款,則將覆蓋描述、默認值和棄用信息(如果指定)月杉。 如果當前模塊中沒有標識手動屬性中的聲明镰踏,則將其作為新屬性添加。
additional-spring-configuration-metadata.json
文件的格式與spring-configuration-metadata.json
文件一樣沙合。 附加屬性文件是可選的奠伪。如果沒有任何其他屬性,就不要添加文件首懈。
參考資料
springboot 配置提示官方文檔
公眾號:逸飛兮(專注于 Java 領域知識的深入學習绊率,從源碼到原理,系統(tǒng)有序的學習)