Spring運(yùn)行環(huán)境Environment的解析
Spring運(yùn)行環(huán)境
Spring在創(chuàng)建容器時(shí),會(huì)創(chuàng)建Environment環(huán)境對(duì)象,用于保存spring應(yīng)用程序的運(yùn)行環(huán)境相關(guān)的信息。在創(chuàng)建環(huán)境時(shí),需要?jiǎng)?chuàng)建屬性源屬性解析器,會(huì)解析屬性值中的占位符,并進(jìn)行替換。
創(chuàng)建環(huán)境時(shí),會(huì)通過System.getProperties()獲取JVM系統(tǒng)屬性,會(huì)通過System.getenv()獲取JVM環(huán)境屬性。
Environment在Spring中的使用
spring在創(chuàng)建容器時(shí)需要指定需要加載配置文件路徑,在加載配置文件路徑時(shí),需要解析字符串中的占位符。解析占位符時(shí),需要環(huán)境信息,此時(shí)會(huì)創(chuàng)建一個(gè)標(biāo)準(zhǔn)的spring運(yùn)行環(huán)境,即創(chuàng)建StandardEnvironment對(duì)象。
1、調(diào)用setConfigLocations方法給spring設(shè)置需要加載的配置文件的路徑,源碼如下:
// 將配置文件的路徑放到configLocations 字符串?dāng)?shù)組中 public void setConfigLocations(@Nullable String... locations) { if (locations != null) { Assert.noNullElements(locations, "Config locations must not be null"); // 設(shè)置了幾個(gè)配置文件,就創(chuàng)一個(gè)多長(zhǎng)的字符串?dāng)?shù)組,用來存放配置文件的路徑 this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { //解析路徑,將解析的路徑存放到字符串?dāng)?shù)組中 this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; } }
2、調(diào)用resolvePath方法解析配置文件路徑中的占位符,源碼如下:
// 解析給定的路徑,必要時(shí)用相應(yīng)的環(huán)境屬性值替換占位符。應(yīng)用于配置位置。 protected String resolvePath(String path) { // 獲取環(huán)境,解決所需的占位符 return getEnvironment().resolveRequiredPlaceholders(path); }
3、調(diào)用getEnvironment方法獲取環(huán)境信息,如果沒有指定spring的環(huán)境信息,通過createEnvironment獲取默認(rèn)的環(huán)境,也就是spring的標(biāo)準(zhǔn)環(huán)境。getEnvironment方法源碼如下:
// 獲取spring的環(huán)境信息,如果沒有指定,獲取到的時(shí)默認(rèn)的環(huán)境 @Override public ConfigurableEnvironment getEnvironment() { if (this.environment == null) { this.environment = createEnvironment(); } return this.environment; }
4、調(diào)用createEnvironment方法獲取默認(rèn)的環(huán)境(spring的標(biāo)準(zhǔn)環(huán)境),使用StandardEnvironment無參構(gòu)造創(chuàng)建對(duì)象。源碼如下:
// 獲取默認(rèn)的環(huán)境 protected ConfigurableEnvironment createEnvironment() { return new StandardEnvironment(); }
Spring的標(biāo)準(zhǔn)環(huán)境StandardEnvironment
Spring的標(biāo)準(zhǔn)環(huán)境StandardEnvironment適合在非web應(yīng)用程序中使用。
在AbstractApplicationContext類的createEnvironment方法中會(huì)調(diào)用StandardEnvironment的無參構(gòu)造方法創(chuàng)建環(huán)境對(duì)象。
1、調(diào)用StandardEnvironment的無參構(gòu)造方法,該方法中沒有任何邏輯處理,源碼如下:
public StandardEnvironment() {}
2、StandardEnvironment類是AbstractEnvironment抽象類的子類,因此使用StandardEnvironment的無參構(gòu)造創(chuàng)建對(duì)象時(shí)會(huì)調(diào)用父類AbstractEnvironment的無參構(gòu)造方法。AbstractEnvironment在下文中有描述。
3、重寫AbstractEnvironment類中的customizePropertySources方法,用于設(shè)置屬性源,該方法通過父類進(jìn)行回調(diào)。
該方法會(huì)獲取JVM系統(tǒng)屬性和環(huán)境屬性并設(shè)置到MutablePropertySources類中存放屬性源的CopyOnWriteArrayList中。
1)JVM系統(tǒng)屬性通過System.getProperties()獲取;
2)環(huán)境屬性通過System.getenv()獲取。
StandardEnvironment類中customizePropertySources方法源碼如下:
// 設(shè)置屬性源,JVM系統(tǒng)屬性中的屬性將優(yōu)先于環(huán)境屬性中的屬性。 @Override protected void customizePropertySources(MutablePropertySources propertySources) { /** * 1、MutablePropertySources類中使用CopyOnWriteArrayList存儲(chǔ)屬性源,集合中存儲(chǔ)PropertySource的子類 * 2、PropertiesPropertySource是PropertySource的子類,PropertySource類中有三個(gè)成員變量 * 1)logger:日志對(duì)象 * 2)name:用來保存屬性源名稱 * 3)source:用來保存屬性源中的屬性 */ // getSystemProperties():通過System.getProperties()獲取JVM屬性鍵值對(duì),并轉(zhuǎn)成Map propertySources.addLast( new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); // getSystemEnvironment():通過System.getenv()獲取環(huán)境屬性鍵值對(duì),并撰成Map propertySources.addLast( new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); }
4、StandardEnvironment類中設(shè)置了兩個(gè)靜態(tài)常量:
1)systemEnvironment:以系統(tǒng)環(huán)境為屬性源
2)systemProperties:以JVM系統(tǒng)屬性為屬性源
/** System environment property source name: {@value}. ?* 系統(tǒng)環(huán)境屬性源名:{@value}。 */ public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment"; /** JVM system properties property source name: {@value}. ?* JVM系統(tǒng)屬性屬性源名稱:{@value}。*/ public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
Spring的抽象環(huán)境AbstractEnvironment
StandardEnvironment類是AbstractEnvironment抽象類的子類,因此使用StandardEnvironment的無參構(gòu)造創(chuàng)建對(duì)象時(shí)會(huì)調(diào)用父類AbstractEnvironment的無參構(gòu)造方法。
1、AbstractEnvironment的無參構(gòu)造方法,該方法會(huì)調(diào)用AbstractEnvironment的有參構(gòu)造方法,源碼如下:
public AbstractEnvironment() { this(new MutablePropertySources()); }
2、AbstractEnvironment的有參構(gòu)造
該方法的主要做三件事:
1)給成員變量賦值
2)創(chuàng)建屬性源屬性解析器
3)調(diào)用子類重寫的customizePropertySources方法(方法回調(diào))。雖然方法回調(diào)在成員變量的賦值之后,但由于是引用傳遞,所以通過成員屬性可以獲取到改變之后的值。
// 使用了模板方法設(shè)計(jì)模式。 // 給成員變量賦值,并調(diào)用子類重寫的方法,對(duì)propertySources進(jìn)行操作。 protected AbstractEnvironment(MutablePropertySources propertySources) { // 給全局變量 可變屬性源 賦值 this.propertySources = propertySources; // 創(chuàng)建屬性解析器:PropertySourcesPropertyResolver 屬性源屬性解析器 this.propertyResolver = createPropertyResolver(propertySources); // 自定義屬性源,此處回調(diào)子類重寫的方法。子類通過重寫該方法可以操作propertySources。spring標(biāo)準(zhǔn)環(huán)境StandardEnvironment重寫了該方法 customizePropertySources(propertySources); }
3、調(diào)用createPropertyResolver創(chuàng)建屬性解析器,用于解析屬性值中的占位符并進(jìn)行替換。
// 在創(chuàng)建環(huán)境時(shí),需要?jiǎng)?chuàng)建屬性解析器 protected ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) { return new PropertySourcesPropertyResolver(propertySources); }
4、AbstractEnvironment的成員屬性
// 指示Spring忽略系統(tǒng)環(huán)境變量,默認(rèn)值為"false"。 // false表示不會(huì)忽略系統(tǒng)環(huán)境變量,此時(shí)getSystemEnvironment方法會(huì)調(diào)用System.getenv()獲取環(huán)境屬性 // true表示會(huì)忽略系統(tǒng)的環(huán)境變量,此時(shí)getSystemEnvironment方法會(huì)返回一個(gè)空的Map public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore"; // 指定系統(tǒng)啟動(dòng)時(shí)使用哪些配置文件,可以使用逗號(hào)隔開 public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active"; // 指定系統(tǒng)啟動(dòng)時(shí)使用默認(rèn)的配置文件,可以使用逗號(hào)隔開 public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default"; // 保留的默認(rèn)的配置文件的名稱,如果沒有顯式設(shè)置默認(rèn)配置文件名稱,也沒有顯式設(shè)置活動(dòng)配置文件名稱,則默認(rèn)情況下該配置文件將自動(dòng)激活。 protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default"; // 日志對(duì)象 protected final Log logger = LogFactory.getLog(getClass()); //系統(tǒng)啟動(dòng)時(shí)使用的配置文件 private final Set<String> activeProfiles = new LinkedHashSet<>(); // 默認(rèn)配置文件 private final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles()); // 可變屬性源,使用該成員變量保存屬性源及通過該屬性源獲取的屬性 private final MutablePropertySources propertySources; // 可配置的屬性解析器 private final ConfigurablePropertyResolver propertyResolver;
到此這篇關(guān)于Spring運(yùn)行環(huán)境Environment的解析的文章就介紹到這了,更多相關(guān)Spring Environment內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot?Test的webEnvironment源碼解讀
- springboot的EnvironmentPostProcessor接口方法源碼解析
- Spring?Boot讀取配置文件內(nèi)容的3種方式(@Value、Environment和@ConfigurationProperties)
- Spring之底層架構(gòu)核心概念Environment及用法詳解
- SpringBoot擴(kuò)展點(diǎn)EnvironmentPostProcessor實(shí)例詳解
- 詳解Spring中的Environment外部化配置管理
- 基于Spring Boot的Environment源碼理解實(shí)現(xiàn)分散配置詳解
- Spring之Environment類的使用方式
相關(guān)文章
Mapper層繼承BaseMapper<T>需要引入的pom依賴方式
這篇文章主要介紹了Mapper層繼承BaseMapper<T>需要引入的pom依賴方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-01-01關(guān)于break和continue以及l(fā)abel的區(qū)別和作用(詳解)
下面小編就為大家?guī)硪黄P(guān)于break和continue以及l(fā)abel的區(qū)別和作用(詳解)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-05-05SpringBoot集成企業(yè)微信開發(fā)的實(shí)現(xiàn)
本文將詳細(xì)介紹如何使用?Spring?Boot?集成企業(yè)微信開發(fā),通過企業(yè)微信?API?可以實(shí)現(xiàn)企業(yè)內(nèi)部的一些自動(dòng)化業(yè)務(wù)流程,提高工作效率,感興趣的可以了解一下2023-07-07如何通過Java實(shí)現(xiàn)PDF轉(zhuǎn)高質(zhì)量圖片
在Java中,將PDF文件轉(zhuǎn)換為高質(zhì)量的圖片可以使用不同的庫,其中最常用的庫之一是?Apache?PDFBox,下面我們就來看看這個(gè)庫的具體使用吧2024-10-10Java源碼解析HashMap的tableSizeFor函數(shù)
今天小編就為大家分享一篇關(guān)于Java源碼解析HashMap的tableSizeFor函數(shù),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01如何保證RabbitMQ全鏈路數(shù)據(jù)100%不丟失問題
這篇文章主要介紹了如何保證RabbitMQ全鏈路數(shù)據(jù)100%不丟失問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Spring實(shí)戰(zhàn)之使用ClassPathResource加載xml資源示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用ClassPathResource加載xml資源,結(jié)合實(shí)例形式分析了Spring使用ClassPathResource加載xml資源的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2019-12-12Spring實(shí)戰(zhàn)之使用@POSTConstruct和@PreDestroy定制生命周期行為操作示例
這篇文章主要介紹了Spring實(shí)戰(zhàn)之使用@POSTConstruct和@PreDestroy定制生命周期行為操作,結(jié)合實(shí)例形式詳細(xì)分析了Spring使用@POSTConstruct和@PreDestroy定制生命周期相關(guān)接口定義、配置與功能實(shí)現(xiàn)技巧,需要的朋友可以參考下2019-12-12