SpringBoot 配置提示功能

提示

目的

配置自動提示的輔助功能可讓配置寫起來更快,準確率大大提升。html

springboot jar 包含提供全部支持的配置屬性細節的元數據文件。文件的目的是爲了讓 IDE 開發者在用戶使用 application.propertiesapplication.yml 文件時提供上下文幫助和代碼補全。java

大多數元數據文件是在編譯時經過處理用 @ConfigurationProperties 註釋的全部項自動生成的。也能夠手動編寫部分元數據。web

版本

參考 SpringBoot 2.2.0.RELEASE 文檔spring

文件

jar包中的 META-INF/spring-configuration-metadata.json (自動生成)或 META-INF/additional-spring-configuration-metadata.json (手動添加)sql

實戰

<!-- 引入相關依賴 -->
<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類型數據的提示 */
  private Map<String, Object> data;
  //注意:使用的時候必需要有getter/setter,不然不會自動生成該屬性對應的提示
  //此處由於篇幅緣由省略 getter/setter
}複製代碼

中文註釋會亂碼,以上故意用中文註釋的地方,會在下面文件中指定對應的描述,看是否會覆蓋。apache

additional-spring-configuration-metadata.jsonjson

{
  "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."
        }
      ]
    }
  ]
}複製代碼

效果

SpringBoot配置提示效果

由此能夠看到如下現象:springboot

  • 代碼中的默認值會自動生成到提示文件中,如: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

分組,將配置類分組。能夠按照文件來分組,即:將同一個配置文件的全部屬性放在同一個組session

屬性
類型
是否必須 用途
name
String Y
分組的完整名稱
type
String N
分組數據類型的類名(如:使用@ConfigurationProperties註釋的完整類名、使用@Bean註釋的方法返回類型)
description
String N
分組的簡短描述。
sourceType
String N
提供分組來源的類名。
sourceMethod String N
提供分組的方法,包含括號和參數類型。

properties

提示主體,必須

屬性
類型
是否必須 用途
name
String
Y
屬性的完整名稱。名稱採用小寫句點分隔格式,如:server.address
type
String
N
屬性數據類型的完整簽名(如:java.lang.String)或完整的泛型類型(如:java.util.Map )。此屬性提示用戶輸入值得類型。原生類型在此處使用其包裝類型(如:boolean使用java.lang.Boolean)。
description
String
N
分組的簡短描述。
sourceType
String
N
提供分組來源的類名。
defaultValue Object
N
默認值。當屬性爲指定時使用。
deprecation
Deprecation N
指定屬性是否已棄用。

deprecation屬性以下:

屬性
類型
是否必須 用途
level
String N
棄用級別,能夠是 warning(默認值) 或 errorwarning:屬性應該仍然可使用;error:屬性不保證可使用
reason
String N
屬性棄用的簡短緣由。
replacement String N
替換此棄用屬性的新屬性全名。可爲空

注意:Spring Boot 1.3 版本以前,是使用 boolean 類型的 deprecated

如下示例來源於官方文檔,展現瞭如何處理這種場景:

`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);

}

}

`

一旦 getTargetsetTarget 方法從公共 API 中刪除,元數據中的自動棄用提示也會消失。 若是要保留提示,則添加具備 error 棄用級別的手動元數據能夠確保用戶仍然瞭解該屬性。在提供替代品時,這樣作特別有用。

hints

輔助提示,非必須

屬性
類型
是否必須 用途
name
String
Y
提示關聯的屬性的完整名稱。名稱是小寫句點分隔格式(如:spring.mvc.servlet.path),若是屬性關聯map類型(如:system.contexts),提示能夠關聯map的鍵(system.contexts.keys)或者值(system.contexts.values)。
values
ValueHint[]
N
有效值集合。(下表詳述)
providers ValueProvider[] N
提供者集合。(下表詳述)

values 屬性以下:

屬性
類型
是否必須 用途
value
Object Y
提示引用元素的有效值。若是屬性是數組,value和description也能夠是數組。
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內每一對 key-value 的提示。

.keys.values 前綴必須分別關聯 Map 的 keys 和 values。

providers 屬性以下:

屬性
類型
是否必須 用途
name
String
N
用於爲提示所引用的元素提供其餘內容幫助的 provider 的名稱。
parameters JSON object N
provider 所支持的任何其餘參數(有關詳細信息,請查看 provider 的文檔)。

ValueProvider

*通常用不到,建議跳過*

下表總結了支持的 providers 列表:

屬性
描述
any
容許提供任何附加值。
class-reference
自動完成項目中可用的類。一般由目標參數指定的基類約束。
handle-as
處理屬性,就像它是由必須的 target 參數定義的類型定義的同樣。
logger-name
自動完成有效的記錄器名稱和記錄器組。一般,當前項目中可用的包和類名能夠自動完成,也能夠定義組。
spring-bean-reference 自動完成當前項目中可用的bean名稱。一般由 target 參數指定的基類約束。
spring-profile-name
自動完成項目中可用的 spring 配置文件名稱。

any

符合屬性類型的全部值。

{"hints": [
    {
        "name": "system.state",
        "values": [
            {
                "value": "on"
            },
            {
                "value": "off"
            }
        ],
        "providers": [
            {
                "name": "any"
            }
        ]
    }
]}複製代碼

class-reference

提供如下參數:

參數
類型
默認值 描述
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 類型時發生,由於您不但願配置類依賴於不在類路徑上的類。

參數
類型
默認值
描述
target String(Class)
Y
爲屬性考慮的類型的徹底限定名。

可用的值以下:

  • 任何 java.lang.Enum: 列出屬性的可能值。
  • java.nio.charset.Charset: 支持自動完成字符集/編碼值(如 utf-8
  • java.util.Locale:自動完成區域設置(如:en_US)
  • org.springframework.util.MimeType:支持自動完成 content-type 值(如: text/plain
  • org.springframework.core.io.Resource: 支持自動完成spring的資源抽象以引用文件系統或類路徑上的文件 (如:classpath:/sample.properties

注意:若是要提供多個值,用 Collection 或 數組類型

{"hints": [
    {
        "name": "spring.liquibase.change-log",
        "providers": [
            {
                "name": "handle-as",
                "parameters": {
                    "target": "org.springframework.core.io.Resource"
                }
            }
        ]
    }
]}複製代碼

logger-name

logger-name provider 自動完成有效的記錄器名稱和記錄器組。 一般,當前項目中可用的包和類名能夠自動完成。 若是組已啓用(默認),而且配置中標識了自定義記錄器組,則應提供該組的自動完成。

支持如下參數:

參數
類型
默認值 描述
group boolean true
指定是否應考慮已知組。

因爲記錄器名稱能夠是任意名稱,此 provider 應容許任何值,但能夠突出顯示項目的類路徑中不可用的有效包和類名。

如下是 logging.level 屬性。keys 是 logger 名,values 關聯標準的 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。 支持如下參數:

{"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"
            }
        ]
    }
]}複製代碼

可重複的元數據項

具備相同「property」和「group」名稱的對象能夠在元數據文件中屢次出現。 例如,能夠將兩個單獨的類綁定到同一前綴,每一個類都有可能重疊的屬性名。 雖然屢次出如今元數據中的相同名稱不該是常見的,但元數據的使用者應注意確保他們支持該名稱。

自動生成提示文件

經過使用 spring-boot-configuration-processor jar,您能夠從用 @ConfigurationProperties 註釋的類中輕鬆生成本身的配置元數據文件。 jar包含一個java註釋處理器,在編譯項目時調用它。 用此處理器,須要引入 spring-boot-configuration-processor 依賴。

`xml

org.springframework.boot

spring-boot-configuration-processor

true

`

處理器獲取用@configurationproperties註釋的類和方法。 配置類中字段值的 javadoc 用於填充 description 屬性。

注意:僅僅只應將簡單文本與@configurationproperties字段javadoc一塊兒使用,由於在將它們添加到json以前不會對它們進行處理。

若是類有一個「至少一個參數」的構造函數,則爲每一個構造函數參數建立一個屬性。 不然,經過標準getter和setter來發現屬性,這些getter和setter對集合類型進行了特殊處理(即便只有getter存在,也會檢測到)。

註解處理器還支持使用@data、@getter和@setter 的 lombok 註解。

註解處理器沒法自動檢測 EnumCollections 的默認值。在集合或枚舉屬性具備非空默認值的狀況下,應提供手動元數據。

@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
    }
}複製代碼

爲了提示上述屬性的默認值,應該手動添加以下元數據:

{"properties": [
    {
        "name": "acme.messaging.addresses",
        "defaultValue": ["a", "b"]
    },
    {
        "name": "acme.messaging.container-type",
        "defaultValue": "simple"
    }
]}複製代碼

注意: 若是在項目中使用 AspectJ,則須要確保註解處理器只運行一次。 使用 Maven 時, 能夠顯式地配置 maven-apt-plugin插件,並僅在那裏向註解處理器添加依賴項。 還可讓 AspectJ 插件運行於全部的處理且在 maven-compiler-pluginconfiguration 中禁用註解處理,以下:

`java

org.apache.maven.plugins

maven-compiler-plugin

none

`

綁定屬性

註解處理器自動將內部類視爲嵌套屬性。

@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.nameserver.host.ipserver.host.port 屬性的元數據信息。 能夠在字段上使用@NestedconfigurationProperty 註解來指示應將常規(非內部)類視爲嵌套類。

注意: 這對集合和映射沒有影響,由於這些類型是自動標識的,而且爲每一個類型生成一個元數據屬性。

添加額外的元數據

Spring Boot 的配置文件處理很是靈活,一般狀況下,可能存在不綁定到 @ConfigurationProperties bean的屬性。 您還可能須要調整現有key的某些屬性,爲了支持這種狀況並讓您提供自定義的「提示」,註解處理器會自動將 META-INF/additional-spring-configuration-metadata.json 中的提示項合併到主要元數據文件(spring-configuration-metadata.json)中

若是引用已自動檢測到的屬性,則將覆蓋描述、默認值和棄用信息(若是指定)。 若是當前模塊中沒有標識手動屬性中的聲明,則將其做爲新屬性添加。

additional-spring-configuration-metadata.json 文件的格式與 spring-configuration-metadata.json 文件同樣。 附加屬性文件是可選的。若是沒有任何其餘屬性,就不要添加文件。

參考資料

springboot 配置提示官方文檔公衆號:逸飛兮(專一於 Java 領域知識的深刻學習,從源碼到原理,系統有序的學習)

逸飛兮

相關文章
相關標籤/搜索