[翻譯]Spring Boot 特征參考2——外部配置:下

本文翻譯自:http://docs.spring.io/spring-boot/docs/2.0.0.M2/reference/htmlsingle/

詳細(xì)介紹Spring boot的關(guān)鍵特征,針對有一定springboot基礎(chǔ)的同學(xué)指巡。

目錄

  • 1 外部配置
    • 1.7 類型安全配置Properties
      • 1.7.1 第三方配置
      • 1.7.2 輕松綁定
      • 1.7.3 屬性轉(zhuǎn)換
      • 1.7.4 @ConfigurationProperties驗證
      • 1.7.5 @ConfigurationProperties vs. @Value

1. 外部配置

1.7 類型安全配置Properties

使用@Value(“$ {property}”)注釋來注入配置屬性有時可能很麻煩犁钟,特別是如果您正在使用多個屬性或數(shù)據(jù)是層次結(jié)構(gòu)的屬性。 Spring Boot提供了一種處理屬性的替代方法稚字,它允許強(qiáng)類型bean來管理和驗證應(yīng)用程序的配置饲宿。

package com.example;

import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("foo")
public class FooProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

上述POJO定義了以下屬性:

  • foo.enabled,默認(rèn)為false
  • foo.remote-address胆描,可以強(qiáng)轉(zhuǎn)為String
  • foo.security.username強(qiáng)制的類型瘫想,其中嵌套的“安全性”的名稱由屬性名稱決定。特別是返回類型并沒有被使用昌讲,并且可以是SecurityProperties
  • foo.security.password
  • foo.security.roles国夜,其中包含String

注意:

Getters和setter通常是強(qiáng)制性的,因為綁定是通過標(biāo)準(zhǔn)的Java Beans屬性描述符短绸,就像在Spring MVC中一樣车吹。在某些情況下可能會忽略一個設(shè)置器:

  • 只要初始化它們就需要一個getter筹裕,但不一定是一個setter,因為它們可以被binder綁定窄驹。
  • 集合和數(shù)組可以通過索引(通常使用YAML)或使用單個逗號分隔值(屬性)來訪問饶碘。在后一種情況下,設(shè)置者是強(qiáng)制性的馒吴。我們建議您始終為此類型添加一個設(shè)置器扎运。如果初始化集合,請確保它不是不可變的(如上例)
  • 如果已初始化嵌套POJO屬性(如上例中的Security字段)饮戳,則不需要setter豪治。如果您希望binder使用其默認(rèn)構(gòu)造函數(shù)即時創(chuàng)建實例,則需要一個setter扯罐。

有些人使用Project Lombok自動添加getter和setter负拟。確保Lombok不會為此類型生成任何特定的構(gòu)造函數(shù)因為它將被容器自動使用來實例化對象。

您還需要列出要在@EnableConfigurationProperties注釋中注冊的屬性類:

@Configuration
@EnableConfigurationProperties(FooProperties.class)
public class MyConfiguration {
}

注意:

當(dāng)@ConfigurationProperties bean以這種方式注冊時歹河,該bean將具有常規(guī)名稱:<prefix>-<fqn>掩浙,在@ConfigurationProperties注釋中指定的環(huán)境密鑰前綴<prefix>和bean的完全限定名稱<fqn>。如果注釋不提供任何前綴秸歧,則僅使用該bean的完全限定名稱厨姚。
上面示例中的bean名稱將是foo-com.example.FooProperties

即使上述配置將為FooProperties創(chuàng)建一個常規(guī)bean键菱,我們建議@ConfigurationProperties僅通過Environment處理谬墙,特別是不從上下文中注入其他bean。話雖如此经备,@EnableConfigurationProperties注釋也會自動應(yīng)用于您的項目拭抬,以便使用@ConfigurationProperties注釋的所有現(xiàn)有bean都將從Environment配置。您可以通過確保FooProperties已經(jīng)是一個bean來快速上面的MyConfiguration

@Component
@ConfigurationProperties(prefix="foo")
public class FooProperties {

    // ... see above

}

這種配置方式與SpringApplication外部YAML配置相當(dāng):

# application.yml

foo:
    remote-address: 192.168.1.1
    security:
        username: foo
        roles:
          - USER
          - ADMIN

# additional configuration as required

要使用@ConfigurationProperties bean侵蒙,您可以像其他任何bean一樣注入它們造虎。

@Service
public class MyService {

    private final FooProperties properties;

    @Autowired
    public MyService(FooProperties properties) {
        this.properties = properties;
    }

     //...

    @PostConstruct
    public void openConnection() {
        Server server = new Server(this.properties.getRemoteAddress());
        // ...
    }

}

使用@ConfigurationProperties還可以生成IDE可以為自己的密鑰提供自動完成的元數(shù)據(jù)文件。

1.7.1 第三方配置

除了使用@ConfigurationProperties來注釋類纷闺,還可以在public @Bean方法中使用它算凿。當(dāng)您希望將屬性綁定到不受控制的第三方組件時,這可能特別有用急但。

要從Environment屬性配置一個bean澎媒,請將@ConfigurationProperties添加到其Bean注冊中:

@ConfigurationProperties(prefix = "bar")
@Bean
public BarComponent barComponent() {
    ...
}

使用bar前綴定義的任何屬性將以與上述FooProperties示例類似的方式映射到該BarComponent bean上

1.7.2 輕松綁定

Spring Boot使用一些輕松的規(guī)則將Environment屬性綁定到@ConfigurationProperties bean,因此不需要在Environment屬性名稱和bean屬性名稱之間進(jìn)行完全匹配波桩。常用的例子是有用的戒努,例如虛線分隔(例如上下文路徑綁定到contextPath)和大寫(例如PORT綁定到端口)環(huán)境屬性。例如,給定以下@ConfigurationProperties類:

@ConfigurationProperties(prefix="person")
public class OwnerProperties {

    private String firstName;

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

}

可以使用以下屬性名稱:

屬性 注意
person.firstName 標(biāo)準(zhǔn)駝峰語法储玫。
person.first-name 虛擬符號侍筛,推薦用于.properties和.yml文件。
person.first_name 下劃線符號撒穷,用于.properties和.yml文件的替代格式匣椰。
PERSON_FIRST_NAME 大寫格式。推薦使用系統(tǒng)環(huán)境變量時端礼。
1.7.3 屬性轉(zhuǎn)換

當(dāng)Spring綁定到@ConfigurationProperties bean時禽笑,Spring將嘗試將外部應(yīng)用程序?qū)傩詮?qiáng)制為正確的類型。如果需要自定義類型轉(zhuǎn)換蛤奥,您可以提供ConversionService bean(使用bean id conversionService)或自定義屬性編輯器(通過CustomEditorConfigurer bean)或自定義轉(zhuǎn)換器(使用注釋為@ConfigurationPropertiesBinding的bean定義)佳镜。

注意:

由于在應(yīng)用程序生命周期中早期請求了該bean,因此請確保限制ConversionService正在使用的依賴關(guān)系凡桥。通常蟀伸,您需要的任何依賴項可能在創(chuàng)建時可能未完全初始化。如果配置密鑰強(qiáng)制不需要缅刽,并且僅依賴使用@ConfigurationPropertiesBinding限定的自定義轉(zhuǎn)換器啊掏,則可能需要重命名自定義ConversionService

1.7.4 @ConfigurationProperties驗證

Spring引導(dǎo)將嘗試使用Spring的@Validated注釋來注釋@ConfigurationProperties類衰猛。您可以直接在配置類上使用JSR-303 javax.validation約束注釋迟蜜。只需確保您的類路徑中符合JSR-303的實現(xiàn),然后在您的字段中添加約束注釋:

@ConfigurationProperties(prefix="foo")
@Validated
public class FooProperties {

    @NotNull
    private InetAddress remoteAddress;

    // ... getters and setters

}

為了驗證嵌套屬性的值腕侄,您必須將關(guān)聯(lián)字段注釋為@Valid以觸發(fā)其驗證小泉。例如,基于上述FooProperties示例:

@ConfigurationProperties(prefix="connection")
@Validated
public class FooProperties {

    @NotNull
    private InetAddress remoteAddress;

    @Valid
    private final Security security = new Security();

    // ... getters and setters

    public static class Security {

        @NotEmpty
        public String username;

        // ... getters and setters

    }

}

您還可以通過創(chuàng)建名為configurationPropertiesValidator的bean定義來添加自定義的Spring Validator冕杠。 @Bean方法應(yīng)該聲明為靜態(tài)的。配置屬性驗證器是在應(yīng)用程序的生命周期早期創(chuàng)建的酸茴,并聲明@Bean方法分预,因為static允許創(chuàng)建bean,而無需實例化@Configuration類薪捍。這避免了早期實例化可能引起的任何問題笼痹。有一個屬性驗證樣本,所以你可以看到如何設(shè)置酪穿。

注意:

spring-boot-actuator模塊包括一個暴露所有@ConfigurationProperties bean的端點凳干。只需將您的Web瀏覽器指向/configprops或使用等效的JMX終結(jié)點。

1.7.5 @ConfigurationProperties vs. @Value

@Value是核心容器功能被济,它不提供與類型安全配置屬性相同的功能救赐。下表總結(jié)了@ConfigurationProperties@Value支持的功能:

Feature @ConfigurationProperties @Value
Relaxed binding Yes No
Meta-data support Yes No
SpEL evaluation No Yes

如果您為自己的組件定義了一組配置密鑰,我們建議您可以將它們分組到使用@ConfigurationProperties注釋的POJO中只磷。還請注意经磅,由于@Value不支持輕松綁定泌绣,如果您需要使用環(huán)境變量提供該值,那么它不是一個很好的候選人预厌。最后阿迈,當(dāng)您可以在@Value中編寫一個SpEL表達(dá)式時,這些表達(dá)式不會從應(yīng)用程序?qū)傩晕募幚怼?/p>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末轧叽,一起剝皮案震驚了整個濱河市苗沧,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌炭晒,老刑警劉巖待逞,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捅僵,死亡現(xiàn)場離奇詭異痊臭,居然都是意外死亡畔乙,警方通過查閱死者的電腦和手機(jī)霹陡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進(jìn)店門卫键,熙熙樓的掌柜王于貴愁眉苦臉地迎上來猿诸,“玉大人卫玖,你說我怎么就攤上這事糟趾÷恳唬” “怎么了休雌?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肝断。 經(jīng)常有香客問我杈曲,道長,這世上最難降的妖魔是什么胸懈? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任担扑,我火速辦了婚禮,結(jié)果婚禮上趣钱,老公的妹妹穿的比我還像新娘涌献。我一直安慰自己,他們只是感情好首有,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布燕垃。 她就那樣靜靜地躺著,像睡著了一般井联。 火紅的嫁衣襯著肌膚如雪卜壕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天烙常,我揣著相機(jī)與錄音轴捎,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛轮蜕,可吹牛的內(nèi)容都是我干的昨悼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼跃洛,長吁一口氣:“原來是場噩夢啊……” “哼率触!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汇竭,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤葱蝗,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后细燎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體两曼,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年玻驻,在試婚紗的時候發(fā)現(xiàn)自己被綠了悼凑。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡璧瞬,死狀恐怖户辫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嗤锉,我是刑警寧澤渔欢,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站瘟忱,受9級特大地震影響奥额,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜访诱,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一垫挨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧触菜,春花似錦棒拂、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谜诫。三九已至漾峡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喻旷,已是汗流浹背生逸。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人槽袄。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓烙无,卻偏偏與公主長得像,于是被迫代替她去往敵國和親遍尺。 傳聞我的和親對象是個殘疾皇子截酷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容