一、元數據格式
提示文件編寫在META-INF的spring-configuration-metadata.json文件下。元數據文件的大部分是在編譯時通過處理所有用@ConfigurationProperties註釋的項目自動生成的。 但是,對於極端情況或更高級的用例,可以手動編寫部分元數據。
配置元數據文件位於META-INF / spring-configuration-metadata.json下的jar內,它們使用簡單的JSON格式,將項目歸類爲【groups】“組”或“【properties】屬性”,並將其他值提示歸類爲【hints】“提示”
每個“屬性”都是用戶使用給定值指定的配置項。 例如,可以在application.properties中指定server.port和server.address,如下所示:
server.port=9090
server.address=127.0.0.1
【group】“組”是更高級別的項目,它們本身並不指定值,而是提供屬性的上下文分組。 例如,server.port和server.address屬性是服務器組的一部分。不需要每個“屬性”都有一個“組”。 某些屬性可能本身就存在。
【hitnts】“提示”是用於幫助用戶配置給定屬性的其他信息。 例如,當開發人員配置spring.jpa.hibernate.ddl-auto屬性時,工具可以使用提示爲無提示提供一些自動完成幫助,驗證,更新,創建和創建放置值。
group的屬性
Name | Type | Purpose |
---|---|---|
|
String |
組的全名。 此屬性是必需的。 |
|
String |
組數據類型的類名。 例如,如果組基於@ConfigurationProperties註解的類,則該屬性將包含該類的完全限定名稱。 如果基於@Bean方法,則它將是該方法的返回類型。 如果類型未知,則可以省略該屬性。 |
|
String |
簡單的描述,需要以 【.】點號結尾 |
|
String |
貢獻此組的源的類名。 例如,如果組基於@ConfigurationProperties註解的@Bean方法,則此屬性將包含包含該方法的@Configuration類的完全限定名稱。 如果源類型未知,則可以省略該屬性。 |
|
String |
貢獻此組的方法的全名(包括括號和參數類型)(例如,@ ConfigurationProperties註釋的@Bean方法的名稱)。 如果源方法未知,則可以省略。 |
Properties的屬性
|
String |
屬性的全名。名稱以小寫的句點分隔(例如server.address )。此屬性是必需的。 |
|
String |
屬性的數據類型的完整簽名(例如java.lang.String ),還包含完整的通用類型(例如java.util.Map<java.util.String,acme.MyEnum> )。您可以使用此屬性指導用戶輸入的值的類型。爲了保持一致性,通過使用原始包裝的對應對象來指定原始類型(例如,boolean 變爲java.lang.Boolean )。請注意,此類可能是一個複雜的類型,當String 綁定值時會從轉換爲此類。如果類型未知,則可以省略。 |
|
String |
可以顯示給用戶的組的簡短描述。如果沒有可用的描述,則可以省略。建議使用簡短的描述,第一行提供簡要的摘要。說明的最後一行應以句點(. )結尾。 |
|
String |
貢獻此屬性的源的類名。例如,如果屬性來自帶有註解的類@ConfigurationProperties ,則此屬性將包含該類的完全限定名稱。如果源類型未知,則可以省略。 |
|
Object |
默認值,如果未指定該屬性,則使用該默認值。如果屬性的類型是數組,則它可以是值的數組。如果默認值未知,則可以省略。 |
|
Deprecation |
指定是否不推薦使用該屬性。如果不建議使用該字段,或者該信息未知,則可以將其省略。下表提供了有關該deprecation 屬性的更多詳細信息。 |
hints提示屬性
Name | Type | Purpose |
---|---|---|
|
String |
該提示所引用的屬性的全名。名稱採用小寫的句點分隔格式(例如 |
|
ValueHint[] |
|
|
ValueProvider[] |
由ValueProvider 對象定義的提供者列表。每個條目定義提供者的名稱及其參數(如果有)。 |
values
每個hint
元素的屬性中包含的JSON對象可以包含下表中描述的屬性:
Name | Type | Purpose |
---|---|---|
|
Object |
用於上面的hints的values。 提示所引用元素的有效值。如果屬性的類型是數組,則它也可以是值的數組。此屬性是必需的。 |
|
String |
可以顯示給用戶的值的簡短描述。如果沒有可用的描述,則可以省略。建議使用簡短的描述,第一行提供簡要的摘要。說明的最後一行應以句點(. )結尾。 |
providers
每個hint
元素的屬性中包含的JSON對象可以包含下表中描述的屬性
名稱 | 類型 | 目的 |
---|---|---|
|
String |
用於爲提示所引用的元素提供附加內容幫助的提供者的名稱。 |
|
JSON對象 |
提供程序支持的任何其他參數 |
二、開發提示
SpringBoot會自動幫我們生成使用@ConfigurationProperties註解下的類的屬性提示,在配置application.yml文件的時候會自動提示。生成的文件夾在Jar的META-INF/spring-configuration-metadata.json文件裏面。
如果我們想要自定義一些提示,並且限制用戶輸入某些屬性的值,需要在開發starter的項目裏面的META-INF文件夾下,創建additional-spring-configuration-metadata.json文件。
2.1 ANY
providers = any
允許提供任何其他值。如果支持,則應基於屬性類型進行常規值驗證。
如果具有值列表,並且任何其他值仍應視爲有效,則通常使用此提供程序。
{
"properties": [
{
"name": "system.user",
"type": "java.lang.String",
"defaultValue": "浙江大學",
"description": "當前登錄系統租戶."
}
],
"hints": [
{
"name": "system.user",
"values": [
{
"value": "浙江大學",
"description": "用戶浙大."
},
{
"value": "北京大學",
"description": "用戶北大."
},
{
"value": "深圳大學",
"description": "用戶深大."
}
],
"providers": [
{
"name": "any"
}
]
}
]
}
導入starter後效果:
在properties裏面的defaultValue是浙江大學,也就是說,推薦提示信息是“浙江大學”。如果不配置,在Controller了面用到了system.user屬性,依然會報錯。這個問題,我特地請教了公司的高級工程師,如何才能從yml中讀取參數,如果讀取不到,就使用默認的值呢?看下面的Java實例。
先從配置文件裏面讀取system.user的值。如果用戶沒有配置,則取冒號後面的默認值。
providers是any這種類型的配置,允許system.user指定任何值。
@RestController
public class HelloController ...
@Value("${system.user:默認的大學}")
private String user;
@GetMapping(value = "/get")
public String function() {
return user;
}
}
2.2 不配置
若hitns裏面不配置任何providers,則system.user的值必須取 hints.values裏面的一個value。嘗試使用非values裏面的配置,則編譯器標紅。
{
"properties": [
{
"name": "system.user",
"type": "java.lang.String",
"defaultValue": "浙江大學",
"description": "當前登錄系統租戶."
}
],
"hints": [
{
"name": "system.user",
"values": [
{
"value": "浙江大學",
"description": "用戶浙大."
},
{
"value": "北京大學",
"description": "用戶北大."
},
{
"value": "深圳大學",
"description": "用戶深大."
}
]
}
]
}
2.3 另外一種固定值的方式:使用枚舉
如果希望調用者配置我們提供好的固定的一些值的時候,使用枚舉也能實現。
package cn.tyzhou.config.hints;
public enum SexEnum {
MAN("1", "男"),
WOMEN("2", "女");
private String code;
private String name;
//constract...
}
{
"properties": [
{
"name": "user.sex",
"description": "管理員性別."
}
],
"hints": [
{
"name": "user.sex",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "cn.tyzhou.config.hints.SexEnum"
}
}
]
}
]
}
2.4 類引用
如果某個property希望使用的是一個類,並且這個類是指定的繼承體系下的類,可以像下面一樣配置。
配置的是java.util.Collection,那麼用戶在配置這個property的時候,只能配置這個類及子類。
{
"properties": [
{
"name": "system.class-name",
"description": "類名."
}
],
"hints": [
{
"name": "system.class-name",
"providers": [
{
"name": "class-reference",
"parameters": {
"target": "java.util.Collection"
}
}
]
}
]
}
根據配置,system.class-name的配置只能是集合框架Collection接口下面的實現類。
2.5 資源文件
如果要讓用戶配置的是當前系統的資源文件,可以向下面一樣配置。
{
"properties": [
{
"name": "log-test.file",
"description": "日誌文件."
}
],
"hints": [
{
"name": "log-test.file",
"providers": [
{
"name": "handle-as",
"parameters": {
"target": "org.springframework.core.io.Resource"
}
}
]
}
]
}
更多配置,請參考SpringBoot官方文檔:configuration-metadata-format