溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

spring和springboot中屬性配置的示例分析

發(fā)布時(shí)間:2021-09-08 13:43:59 來(lái)源:億速云 閱讀:184 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章將為大家詳細(xì)講解有關(guān)spring和springboot中屬性配置的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

在xml中注冊(cè)屬性文件

通過(guò)在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.2.xsd
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-4.2.xsd">
      <context:property-placeholder location="classpath:foo.properties" />
</beans>

foo.properties文件可以放在/src/main/resources文件夾中,即運(yùn)行時(shí)類(lèi)路徑。

多個(gè)

如果在Spring上下文中出現(xiàn)了多個(gè) 元素,那么應(yīng)該遵循以下幾個(gè)最佳實(shí)踐:

  • 需指定order屬性來(lái)確定spring處理順序

  • 需要引用其他原始屬性元素應(yīng)該增加ignore-unresolvable= “true”,使解析機(jī)制先不拋出異常的情況下繼續(xù)加載其他配置。

通過(guò)java注解方式注冊(cè)屬性文件

Spring 3.1 引入新的 @PropertySource 注解,可以方便地給spring environment中添加property source。該注解與基于Java Configuration 方式配置的@Configuration注解一起使用:

@Configuration
@PropertySource("classpath:foo.properties")
public class PropertiesWithJavaConfig {
    //...
}

另一個(gè)非常有用的注冊(cè)方式為使用占位符方式實(shí)現(xiàn)運(yùn)行時(shí)動(dòng)態(tài)選擇屬性文件,示例如下:

@PropertySource({ 
  "classpath:persistence-${envTarget:mysql}.properties"
})
…

使用及注入屬性

直接通過(guò) @Value 注解注入屬性:

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

也可以指定缺省值:

@Value( "${jdbc.url:aDefaultUrl}" )
private String jdbcUrl;

在 Spring XML configuration使用屬性:

<bean id="dataSource">
  <property name="url" value="${jdbc.url}" />
</bean>

舊的 PropertyPlaceholderConfigurer 和新的 PropertySourcesPlaceholderConfigurer(Spring 3.1 中引入)都可以解析xml bean定義和@value注解中的 ${…} 占位符 。

最后,使用新的Environment API可以獲取屬性值:

@Autowired
private Environment env;
...
dataSource.setUrl(env.getProperty("jdbc.url"));

特別需要注意的是,使用不會(huì)暴露屬性給 Spring Environment,這意味這下面代碼會(huì)返回null:

env.getProperty("key.something")

屬性搜索優(yōu)先級(jí)

spring4中,默認(rèn)local properties文件最后加載,environment Properties和system Properties之后。local properties是通過(guò)PropertiesLoaderSupport 類(lèi)的API方法 (setProperties, setLocation, etc)手工或編程方式配置的。

這種機(jī)制可以通過(guò)設(shè)置PropertySourcesPlaceholderConfigurer類(lèi)的localOverride 屬性進(jìn)行修改,值為true允許local properties覆蓋spring系統(tǒng)加載的。

spring3.0之前,PropertyPlaceholderConfigurer 類(lèi)嘗試在手工定義源和System Properties兩個(gè)地方查找,查找順序也可以通過(guò)設(shè)置systemPropertiesMode屬性進(jìn)行配置:

  • never – 總不檢查 system properties

  • fallback (default) – 如果指定的properties files查找不到,則檢查 system properties

  • override – 先檢查system properties,然后再?lài)L試指定的properties files。這允許system properties覆蓋任何其他屬性源。

最后需注意,如果在兩個(gè)或多個(gè)通過(guò)@PropertySource定義了屬性,那么最后一個(gè)定義優(yōu)先級(jí)最高并覆蓋以前的定義。這使得準(zhǔn)確的屬性值難以預(yù)測(cè),所以如果覆蓋不滿(mǎn)足需求,那么可以重寫(xiě)PropertySource API。

spring boot 屬性加載

在我們進(jìn)入更高級(jí)的屬性配置之前,讓我們先看看Spring Boot中屬性加載的新特性。

總的來(lái)說(shuō)與標(biāo)準(zhǔn)Spring相比,這種新支持的配置更少,當(dāng)然這是Spring Boot的主要目標(biāo)之一。

application.properties – 缺省屬性文件

spring boot 應(yīng)用是典型基于配置文件規(guī)范約定。我們可以簡(jiǎn)單地放“application.properties” 文件在“src/main/resources”目錄中,spring boot會(huì)自定監(jiān)測(cè),我們能在其中放入任何屬性。

通過(guò)使用缺省文件,我們無(wú)須顯示注冊(cè)PropertySource并指定屬性文件路徑。我們也可以在運(yùn)行時(shí)使用環(huán)境變量屬性指定不同的屬性配置文件:

java -jar app.jar --spring.config.location=classpath:/another-location.properties

特定環(huán)境屬性文件

如果我們需要針對(duì)不同環(huán)境,spring boot內(nèi)置機(jī)制可以滿(mǎn)足。我們可以在“src/main/resources”目錄中定義“application-environment.properties” 文件,然后設(shè)置spring profile與environment名稱(chēng)一致。

例如,如果我們定義“staging” 環(huán)境變量,則我們必須定義staging profile,然后定義application-staging.properties屬性文件。

特定環(huán)境屬性文件加載優(yōu)先級(jí)高于缺省屬性文件。注意,默認(rèn)文件仍然會(huì)被加載,只是當(dāng)有屬性沖突時(shí),特定環(huán)境屬性文件優(yōu)先。

特定測(cè)試屬性文件

在應(yīng)用測(cè)試階段,我們可能需要不同的屬性值。Spring Boot通過(guò)在測(cè)試運(yùn)行期間查找“src/test/resources”目錄中的屬性文件來(lái)處理這個(gè)問(wèn)題。同樣,默認(rèn)屬性仍然會(huì)被加載,但是如果發(fā)生沖突,將會(huì)覆蓋這些屬性。

@TestPropertySource注解

如果需要更細(xì)粒度控制測(cè)試屬性,我們可以使用@TestPropertySource注解。其可以設(shè)置給測(cè)試上下文設(shè)置測(cè)試屬性,比缺省屬性源優(yōu)先級(jí)高:

@ContextConfiguration
@TestPropertySource("/my-test.properties")
public class IntegrationTests {
    // tests
}

如果我們不想使用文件,也直接指定名稱(chēng)和值:

@ContextConfiguration
@TestPropertySource("foo=bar", "bar=foo")
public class IntegrationTests {
    // tests
}

也可以通過(guò)@SpringBootTest注解,指定相應(yīng)properties參數(shù)值達(dá)到同樣效果:

@SpringBootTest(properties = {"foo=bar", "bar=foo"})
public class IntegrationTests {
    // tests
}

層次屬性

如果屬性按分組形式配置,可以使用 @ConfigurationProperties注解,其會(huì)按照對(duì)象圖方式映射這些分層組織屬性。下面示例看看數(shù)據(jù)庫(kù)連接配置屬性:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar

然后使用注解映射至數(shù)據(jù)庫(kù)對(duì)象:

@ConfigurationProperties(prefix = "database")
public class Database {
    String url;
    String username;
    String password;
    // standard getters and setters
}

spring boot 在配置方法中再次應(yīng)用了基于約定原則,自動(dòng)映射屬性值對(duì)象字段,我們僅需提供屬性前綴即可。

YAML 文件

YAML文件也支持。

同樣名稱(chēng)規(guī)則可以應(yīng)用至測(cè)試規(guī)范、environmet規(guī)范以及缺省屬性文件。僅文件擴(kuò)展名不同以及需提供SnakeYAML依賴(lài)。

YAML對(duì)層次屬性存儲(chǔ)特別方便,下面的屬性文件:

database.url=jdbc:postgresql:/localhost:5432/instance
database.username=foo
database.password=bar
secret: foo

對(duì)應(yīng)的YAML文件為:

database:
  url: jdbc:postgresql:/localhost:5432/instance
  username: foo
  password: bar
secret: foo

需要注意的是YAML文件不支持使用@PropertySource注解,所以如果使用該注解則必須使用屬性文件。

命令行傳入屬性

相對(duì)于使用文件,屬性也可以直接通過(guò)命令行進(jìn)行傳遞:

java -jar app.jar --property="value"

你也能通過(guò)系統(tǒng)屬性實(shí)現(xiàn),需要在-jar命令之前提供:

java -Dproperty.name="value" -jar app.jar

環(huán)境變量屬性

spring boot也能監(jiān)測(cè)環(huán)境變量,效果與屬性一樣:

export name=value
java -jar app.jar

隨機(jī)屬性值

如果屬性值不確定,RandomValuePropertySource 可以實(shí)現(xiàn)給屬性賦隨機(jī)值:

random.number=${random.int}
random.long=${random.long}
random.uuid=${random.uuid}

其他類(lèi)型的屬性源

spring boot 支持很多屬性源,實(shí)現(xiàn)較好順序及合理覆蓋。其官方文檔可以參閱。

spring配置實(shí)現(xiàn)

  • spring3.1之前

spring3.1引入注解,可以方便地定義屬性源,在此之前,xml配置是必須的。 xml元素自動(dòng)在spring上下文中注冊(cè)新的PropertyPlaceholderConfigurer bean。為了向后兼容,在spring3.1及之后版本中,如果XSD schemas不升級(jí)到新的3.1 XSD版本,仍然會(huì)創(chuàng)建相應(yīng)bean。

  • spring3.1之后

從spring3.1起,XML 元素不再注冊(cè)舊的PropertyPlaceholderConfigurer 類(lèi),代替引入PropertySourcesPlaceholderConfigurer類(lèi),新的類(lèi)可以實(shí)現(xiàn)更靈活地和Environment 和 PropertySource機(jī)制進(jìn)行交互。

對(duì)3.1之后版本,應(yīng)該應(yīng)用新的標(biāo)準(zhǔn)。

多層級(jí)上下文中屬性加載

當(dāng)web應(yīng)用有父和子上下文時(shí),屬性如何加載是很常見(jiàn)的問(wèn)題。父上下文有一些通用的核心功能和bean,并包括一個(gè)或多個(gè)子上下文,可能包含servlet特定的bean。

這種場(chǎng)景下,如何最佳方式定義屬性文件并引入到各自的上下文中?以及如何在spring中以最佳方式獲取這些屬性,下面分類(lèi)進(jìn)行說(shuō)明:

屬性文件通過(guò)定義xml中

如果文件定義在父上下文:

  • @Value 在子上下文 : 否

  • @Value 在父上下文 : 是

如果文件定義在子上下文:

  • @Value 在子上下文 : 是

  • @Value 在父上下文 : 否

總之如上所述,沒(méi)有暴露屬性給environment,所以environment.getProperty在上下文中不工作。

屬性文件通過(guò)@PropertySource定義在java中

如果文件定義在父上下文:

  • @Value 在子上下文 : 是

  • @Value 在父上下文 : 是

  • environment.getProperty 在子上下文: 是

  • environment.getProperty 在父上下文: 是

如果文件定義在子上下文:

  • @Value 在子上下文 : 是

  • @Value 在父上下文 : 否

  • environment.getProperty 在子上下文: 是

  • environment.getProperty 在父上下文: 否

關(guān)于“spring和springboot中屬性配置的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI