(2) spring-boot配置詳解

Spring Boot簡化了基于Spring的應用開發,其為spring及第三方平臺提供開箱即用的設置,多數Spring Boot應用只需要很少的Spring配置。

spring特性:

  • 為所有Spring開發提供一個從根本上更快,且隨處可得的入門體驗。
  • 開箱即用,但通過不采用默認設置可以快速擺脫這種方式。
  • 提供一系列大型項目常用的非功能性特征,比如:內嵌服務器,安全,指標,健康檢測,外部化配置。
  • 絕對沒有代碼生成,也不需要XML配置。

1、Spring-Boot核心配置文件

SpringBoot配置文件可以使用yml格式和properties格式,分別的默認命名為:application.yml、application.properties

配置.png

1.1、存放目錄

  • 項目根目錄下
  • 項目根目錄中config目錄下
  • 項目的resources目錄下
  • 項目resources目錄中config目錄下
項目.png

1.2、讀取順序

如果在不同的目錄中存在多個配置文件,它的讀取順序是:

  1. config/application.properties(項目根目錄中config目錄下)
  2. config/application.yml
  3. application.properties(項目根目錄下)
  4. application.yml
  5. resources/config/application.properties(項目resources目錄中config目錄下)
  6. resources/config/application.yml
  7. resources/application.properties(項目的resources目錄下)
  8. resources/application.yml

注:

1、如果同一個目錄下,有application.yml也有application.properties,默認先讀取application.properties。
2、如果同一個配置屬性,在多個配置文件都配置了,默認使用第1個讀取到的,后面讀取的不覆蓋前面讀取到的。
3、創建SpringBoot項目時,一般的配置文件放置在“項目的resources目錄下”

1.3、更改默認配置文件位置

如果不喜歡將application.properties作為配置文件名,你可以通過指定spring.config.name環境屬性來切換其他的名稱,也可以使用spring.config.location環境屬性引用一個明確的路徑(目錄位置或文件路徑列表以逗號分割)。

$ java -jar myproject.jar --spring.config.name=myproject

$ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

注意:

(1)、在初期需要根據spring.config.name和spring.config.location決定加載哪個文件,所以它們必須定義為environment屬性(通常為OS env,系統屬性或命令行參數)。
(2)、如果spring.config.location包含目錄(相對于文件),那它們應該以/結尾(在被加載前,spring.config.name關聯的名稱將被追加到后面,包括profile-specific的文件名)。spring.config.location下定義的文件使用方法跟往常一樣,沒有profile-specific變量支持的屬性,將被profile-specific的屬性覆蓋。
(3)、不管spring.config.location配置什么值,默認總會按照classpath:,classpath:/config,file:,file:config/的順序進行搜索,優先級由低到高,也就是file:config/獲勝。如果你指定自己的位置,它們會優先于所有的默認位置(locations),并使用相同的由低到高的優先級順序。那樣,你就可以在application.properties為應用設置默認值,然后在運行的時候使用不同的文件覆蓋它,同時保留默認配置。

2、spring-boot讀取配置

spring-boot的核心配置文件為application.properties,同時也可通過注解自定義配置文件。

2.1、使用@Value方式讀取核心配置

使用方法:

@Value("${xxx}")

使用示例:

package Solin.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {
  @Value("${test.msg}")
  private String msg;

  @RequestMapping("/index1")
  public String index1(){
    return "方式一:"+msg;
  }
}

注意事項:

在@Value的${}中包含的是核心配置文件application.properties中的鍵名。

2.1、使用Environment方式

使用方法:
用注入Environment實例,通過Environment.getProperty("xxx")獲取配置信息;

使用示例:

package Solin.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {
  @Autowired
  private Environment env;

  @RequestMapping("/index2")
  public String index2(){
    return "方式二:"+env.getProperty("test.msg");
  }
}

注意事項:

(1)、這種方式是依賴注入Evnironment來完成,在創建的成員變量private Environment env上加上@Autowired注解即可完成依賴注入,然后使用env.getProperty("鍵名")即可讀取出對應的值。
(2)、Evnironment不僅能獲取核心配置application.properties的參數,還能獲取應用運行的一些環境參數,例如:env.getProperty("JAVA_HOME"),env.getProperty("CLASSPATH")等;

2.3、使用@ConfigurationProperties讀取

@ConfigurationProperties可以讀取核心配置application.properties中的配置,也可讀取自定義的配置;

使用方法:

使用@Component及@ConfigurationProperties一起生成配置bean;若要讀取自定義配置,則還需@PropertySource配合使用;

使用示例:

代碼:

@Component
@ConfigurationProperties(value = "my")
@PropertySource("classpath:config/myconfig.properties")

public class TestConfigurationProperties {
private String name;
private int age;
private String sex;

//getter、setter方法
}

myconfig.properties配置:

my.name = zhaozhou
my.age = 20
my.sex = man

說明:

  • 示例中@ConfigurationProperties(value = "my"),設置屬性組前綴,與@ConfigurationProperties(prefix= "my")等同;
  • @PropertySource(value="classpath:config/myconfig.properties")加載指定的屬性文件,value設置自定義配置文件的位置,此配置可以放在此位置,也可放在其他位置;

3、外化配置

3.1、配置隨機值

在注入隨機值(比如,密鑰或測試用例)時RandomValuePropertySource很有用,它能產生整數,longs或字符串,比如:

my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.number.less.than.ten=${random.int(10)}
my.number.in.range=${random.int[1024,65536]}

random.int*語法是OPEN value (,max) CLOSE,此處OPEN,CLOSE可以是任何字符,并且value,max是整數。如果提供max,那么value是最小值,max是最大值(不包含在內)。

3.2、訪問命令行屬性

默認情況下,SpringApplication會將所有命令行配置參數(以'--'開頭,比如--server.port=9000)轉化成一個property,并將其添加到Spring Environment中。正如以上章節提過的,命令行屬性總是優先于其他屬性源。如果不想將命令行屬性添加到Environment,你可以使用SpringApplication.setAddCommandLineProperties(false)來禁用它們。

3.3、Profile-specific屬性

除了application.properties文件,profile-specific屬性也能通過命名慣例application-{profile}.properties定義。Environment(Spring的環境抽象接口)有個默認profiles集合(默認情況為[default]),在沒有設置激活的profiles時會被使用(例如,如果沒有明確指定激活的profiles,application-default.properties中的屬性會被加載)。Profile-specific屬性加載路徑和標準的application.properties相同,并且profile-specific文件總是會覆蓋non-specific文件,不管profile-specific文件是否被打包到jar中。如果定義多個profiles,最后一個將獲勝。例如,spring.profiles.active定義的profiles被添加到通過SpringApplicationAPI定義的profiles后面,因此優先級更高。

注意:如果你已經在spring.config.location下定義所有文件(非目錄),那些profile-specific的文件將不被考慮。如果想使用profile-specific屬性,那就在spring.config.location下使用目錄。

3.4、屬性占位符

當使用application.properties定義的屬性時,Spring會先通過已經存在的Environment查找該屬性,所以你可以引用事先定義的值(比如,系統屬性):

app.name=MyApp
app.description=${app.name} is a Spring Boot application

4、類型安全的配置屬性

4.1、第三方配置

@ConfigurationProperties不僅可以注解在類上,也可以注解在public @Bean方法上,當你需要為不受控的第三方組件綁定屬性時,該方法將非常有用。為了從Environment屬性中配置一個bean,你需要使用@ConfigurationProperties注解該bean:

@ConfigurationProperties(prefix = "foo") 
@Bean public FooComponent fooComponent() {
   …… 
}

所有以foo為前綴的屬性定義都會被映射到FooComponent上。

4.2、Relaxed綁定

Spring Boot將Environment屬性綁定到@ConfigurationProperties beans時會使用一些寬松的規則,所以Environment屬性名和bean屬性名不需要精確匹配。常見的示例中有用的包括虛線分割(比如,context-path綁定到contextPath),將environment屬性轉為大寫字母(比如,PORT綁定port)。

例如,給定以下@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 標準駝峰規則
person.first-name 虛線表示,推薦用于.properties和.yml文件中
person.first_name 下劃線表示,用于.properties和.yml文件的可選格式
PERSON_FIRST_NAME 大寫形式,使用系統環境變量時推薦

4.3、屬性轉換

將外部應用配置綁定到@ConfigurationProperties beans時,Spring會嘗試將屬性強制轉換為正確的類型。如果需要自定義類型轉換器,你可以提供一個ConversionService bean(bean id為conversionService),或自定義屬性編輯器(通過CustomEditorConfigurer bean),或自定義Converters(bean定義時需要注解@ConfigurationPropertiesBinding)。

注意:由于該bean在應用程序生命周期的早期就需要使用,所以確保限制你的ConversionService使用的依賴。通常,在創建時期任何你需要的依賴可能都沒完全初始化。

4.4、@ConfigurationProperties校驗

Spring Boot將嘗試校驗外部配置,默認使用JSR-303(如果在classpath路徑中),你只需要將JSR-303 javax.validation約束注解添加到@ConfigurationProperties類上:

@ConfigurationProperties(prefix="connection") 
public class ConnectionProperties { 
  @NotNull 
  private InetAddress remoteAddress; 

  // ... getters and setters 
}

為了校驗內嵌屬性的值,你需要使用@Valid注解關聯的字段以觸發它的校驗,例如:

@ConfigurationProperties(prefix="connection") 
public class ConnectionProperties { 
  @NotNull 
  @Valid 
  private RemoteAddress remoteAddress; 
  
  // ... getters and setters 
  public static class RemoteAddress { 
    @NotEmpty 
    public String hostname; 
    // ... getters and setters 
  } 
}

你也可以通過創建一個叫做configurationPropertiesValidator的bean來添加自定義的Spring Validator。@Bean方法需要聲明為static,因為配置屬性校驗器在應用程序生命周期中創建的比較早,將@Bean方法聲明為static允許該bean在創建時不需要實例化@Configuration類,從而避免了早期實例化(early instantiation)的所有問題。

4.5、@ConfigurationProperties與@Value對比

@Value是Spring容器的一個核心特性,它沒有提供跟type-safe Configuration Properties相同的特性。下面的表格總結了@ConfigurationProperties和@Value支持的特性:

特性 @ConfigurationProperties @Value
Relaxed綁定 Yes No
Meta-data支持 Yes No
SpEL表達式 No Yes

如果你為自己的組件定義了一系列的配置keys,我們建議你將它們以@ConfigurationProperties注解的POJO進行分組。由于@Value不支持relaxed綁定,所以如果你使用環境變量提供屬性值的話,它就不是很好的選擇。最后,盡管@Value可以寫SpEL表達式,但這些表達式不會處理來自Application屬性文件的屬性。

5、profiles配置

Spring Profiles提供了一種隔離應用程序配置的方式,并讓這些配置只在特定的環境下生效。任何@Component或@Configuration都能注解@Profile,從而限制加載它的時機:

@Configuration @Profile("production") 
public class ProductionConfiguration { 
  // ... 
}

以正常的Spring方式,你可以使用spring.profiles.active的Environment屬性來指定哪個配置生效。你可以使用通常的任何方式來指定該屬性,例如,可以將它包含到application.properties中:

spring.profiles.active=dev,hsqldb

或使用命令行開關:

--spring.profiles.active=dev,hsqldb

5.1、添加激活的配置(profiles)

spring.profiles.active屬性和其他屬性一樣都遵循相同的排列規則,優先級最高的PropertySource獲勝,也就是說,你可以在application.properties中指定生效的配置,然后使用命令行開關替換它們。有時,將profile-specific的屬性添加到激活的配置中而不是直接替換它們是有好處的。spring.profiles.include屬性可以用來無條件的添加激活的配置,而SpringApplication的入口點也提供了一個用于設置其他配置的Java API,通過它設置的active配置優先級高于spring.profiles.active,具體參考setAdditionalProfiles()方法。

例如,當一個應用使用下面的屬性,并用--spring.profiles.active=prod開關運行,那proddb和prodmqprofiles也會激活:

--- my.property: fromyamlfile 
--- spring.profiles: prod spring.profiles.include: proddb,prodmq

5.2、以編程方式設置profiles

在應用運行前,你可以通過調用SpringApplication.setAdditionalProfiles(…)方法,以編程的方式設置激活的配置,也可以使用Spring的ConfigurableEnvironment接口激活配置(profiles)。

5.3、Profile-specific配置文件

Profile-specific的配置,不管是application.properties(或application.yml),還是通過@ConfigurationProperties引用的文件都是被當作文件來加載的。

6、@import注解與@ImportResource注解

  • @Import注解就是之前xml配置中的import標簽,可以用于依賴第三方包中bean的配置和加載
  • @ImportResource是引入spring配置文件.xml

6.1、@import

import注解主要用在基于java代碼顯式創建bean的過程中,用于將多個分散的java config配置類融合成一個更大的config類;

代碼示例:

package com.yiibai.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import({ CustomerConfig.class, SchedulerConfig.class })
public class AppConfig {
}

6.2、@ImportResource

用于導入自定義的xml配置,相當于:

<import resource="applicationContext-democonfig2.xml" />

代碼示例:

@Configuration
@ImportResource("classpath:applicationContext-democonfig2.xml")
public class StoreConfig {

  @Value("${url}")
  private String url;

  @Value("${username}")
  private String username;

  @Value("${password}")
  private String password;

  @Bean
  public MyDriverManager myDriverManager() {
    return new MyDriverManager(url, username, password);
  }
}

XML代碼:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.1.xsd">

<context:property-placeholder location="classpath:config4.properties" />
<context:component-scan base-package="com.dxz.imports4"></context:component-scan>
</beans>

<context:property-placeholder location="classpath:config4.properties" />用于指導資源文件位置。

7、Java配置類

Spring Boot提倡基于Java的配置。盡管你可以使用XML源調用SpringApplication.run(),不過還是建議你使用@Configuration類作為主要配置源。通常定義了main方法的類也是使用@Configuration注解的一個很好的替補。

7.1、導入其他配置類

你不需要將所有的@Configuration放進一個單獨的類,@Import注解可以用來導入其他配置類。另外,你也可以使用@ComponentScan注解自動收集所有Spring組件,包括@Configuration類。

7.2、導入XML配置

如果必須使用XML配置,建議你仍舊從一個@Configuration類開始,然后使用@ImportResource注解加載XML配置文件。

8、快速查閱

相關閱讀:
spring-boot基礎環境搭建 【http://www.lxweimin.com/p/ee36bb9faa10
spring-boot+druid+mybatis環境搭建【http://www.lxweimin.com/p/e6c9e9945e45
spring-boot+logback+log4j2+MDC【http://www.lxweimin.com/p/51da61a425ba

參考博客:
https://blog.csdn.net/qq_32786873/article/details/52840745
http://www.lxweimin.com/p/60b34464ca58
https://www.cnblogs.com/duanxz/p/3787757.html

參考書籍:
《Spring Boot參考指南》 (https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/III.%20Using%20Spring%20Boot/15.2.%20Importing%20XML%20configuration.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容