国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

源碼解讀 Spring Boot Profiles

Dionysus_go / 3558人閱讀

摘要:有了配置文件之后,啟動程序,我們首先可以看到日志輸入,由此可以看出程序讀取了的配置。首先,根據的全局查找功能,直接搜索這些詞出現的位置,進行定位,可以找到這個日志出現于方法之中。由于我們的配置文件在下,所以只要留意當為的程序執行情況即可。

前言

上文《一文掌握 Spring Boot Profiles》 是對 Spring Boot Profiles 的介紹和使用,因此本文將從源碼角度探究 Spring Boot Profiles,讓我們看下 Spring Boot 底層是如何應用 Profiles 進行環境配置的隔離與生效的。

正文

首先,我們先來看下一個簡單的 Spring Boot 示例程序,

在主程序方法中,打印容器中獲取到 User 對象,它只有一個 name 屬性。

這里 name 屬性引用了外部配置 user.username 的值,它是從配置文件中讀取,這里我定義兩個配置文件設置該屬性,application.propertiesapplication-prod.properties

有了配置文件之后,啟動 SimapleSpringApplication 程序,我們首先可以看到日志輸入:User Bean: User(name=one),由此可以看出程序讀取了 application.propertiesuser.username 配置。現在我們在 application.properties 中加入一行:

再次重啟啟動程序,可以看到控制臺如下日志:

此時 User 對象的name屬性變成了 application-prod.properties 中定義的值,并且日志提示 The following profiles are active: prod 表明了名稱為 prod 的Profile 在程序中激活。接下來我們就從這個日志入手,探究下這一切是如何發生的。

首先,根據 IDE 的全局查找功能,直接搜索 The following profiles are active: 這些詞出現的位置,進行定位,可以找到這個日志出現于 SpringApplication#logStartupProfileInfo 方法之中。

從日志方法可以看出打印的 activeProfiles 來自上下文關聯的 environment 對象,再進一步查看 logStartupProfileInfo 的調用位置,可以在 SpringApplication#prepareContext 方法之中找到,這個方法從命名上就可以看出是主要負責 Spring Boot 運行前容器上下文的預備工作,

我們重新運行程序,通過斷點方式攔截 SpringApplication#prepareContext 方法的指向, 獲取 environment 對象真實的類型為 StandardEnvironment,是 Environment 接口非Web環境的標準實現,存儲著一些應用配置和 Profiles 信息,如果在Web環境下,context 關聯的就是 StandardServletEnvironment 類型的對象。

知道了日志打印來自 StandardEnvironment 對象的 activeProfiles 屬性之后,就需要來看它是在什么時間被賦值的了。繼續從調用鏈的上一級查找,就到了 SpringApplication#run(java.lang.String...),這也是整個程序啟動的主要方法。

從圖中可以看出第一次獲取到的 environment 對象來自 SpringApplication#prepareEnvironment 內部生成, prepareEnvironment 方法內部首先通過 getOrCreateEnvironment 獲取一個基礎的 ConfigurableEnvironment 實例,然后對該實例對象初始化配置返回。

正在創建 environment 對象來自 SpringApplication#getOrCreateEnvironment,看它的實現就可以驗證我們之前提到 environment 對象類型為 StandardEnvironment。

了解完 environment 的創建,接下來就關注 environment 的初始化了,這里我們需要關注 listeners.environmentPrepared(environment) 這行代碼,這里的 listeners 為 SpringApplicationRunListeners 實例,是監聽器 SpringApplicationRunListener 的集合對象, SpringApplicationRunListener#environmentPrepared 方法中就是對每個 SpringApplicationRunListener 對象遍歷指向類似的 environmentPrepared 方法,當前集合中只有一個 EventPublishingRunListener 實例,查看其 environmentPrepared 方法就可以看到它主要就是用于發布包含 environment 實例的 ApplicationEnvironmentPreparedEvent 事件,讓其他所有監聽該事件的監聽器進行 environment 實例的配置。

事件對象 ApplicationEnvironmentPreparedEvent 還有一個 getEnvironment 方法獲取所傳遞的 environment實例,我們可以通過看這個方法被使用的地方,獲取有哪些類在配置 environment 對象。

經過多次的查看,從上圖可以定位到 ConfigFileApplicationListener 類內的方法對 environment 對象進行擴展,從命名可以看出這個監聽器跟配置文件相關,比如它的一些常量屬性:CONFIG_NAME_PROPERTYCONFIG_LOCATION_PROPERTY 等。從類的注釋可以看出,Spring Boot 程序啟動所加載的 application.propertiesapplication.yml 默認從四個路徑下加載,我們最常用的就是最后一種,它也可以告訴我們還可以把配置文件放在哪,如何自定義加載配置文件的路徑。

file:./config/:

file:./

classpath:config/

classpath:

將程序斷點設置于 ConfigFileApplicationListener#onApplicationEvent 方法之內,重新運行程序就看到程序此時運行到了 ConfigFileApplicationListener 類之中,內部經過多個方法調用從 onApplicationEvent 來到了 addPropertySources 方法,這個方法就是配置文件的屬性源加載到 environment 環境去的。

這里的 LoaderConfigFileApplicationListener類內部私有類,用于協調屬性源和配置 Profiles,我們再進一步跟蹤到它的 load 方法。

我們主要看這個方法中的是三個方法:

Loader#initializeProfiles

Loader#addProfileToEnvironment

Loader#load(Profile, DocumentFilterFactory, DocumentConsumer)

第一個方法 initializeProfiles 初始化 Profiles,給 profiles 屬性添加兩個元素,null 和 默認的Profile。

第二個方法 addProfileToEnvironment 就是將 Profile 添加到 environment 對象的 activeProfiles 里,也就是最開始日志打印的 activeProfiles

第三個方法就是加載配置文件的數據源和 Profies 相關的屬性。

進入 load 方法,這個方法內部通過不同配置路徑去嘗試執行另一個 load 方法加載配置文件,這里 name 就是配所要搜索的配置文件名稱,默認為 application

由于我們的配置文件在 ClassPath 下,所以只要留意當 locationclasspath:/ 的程序執行情況即可。

由于SpringBoot 配置文件支持xmlpropertiesyml 格式,就需要不同 PropertySourceLoader 支持其文件內容的加載:PropertiesPropertySourceLoader 支持 xmlproperties 文件,YamlPropertySourceLoader 支持 yml 文件,加載以 .yml.yaml 后綴的文件,Loader#loadForFileExtension 方法就完成了對這些配置文件的加載。

我們示例程序只有 properties 文件,所以只需要關注當 loader 為 PropertiesPropertySourceLoader時的 Loader#loadForFileExtension 方法的執行情況。

loadForFileExtension 內部調用另外一個加載配置文件的 load 方法,當讀取到ClassPath下的application.properties 時,會執行到 Loader#loadDocuments 方法,這個方法就是把配置文件作為文檔進行加載,所有鍵值對配置都會以存在 PropertySource 之中,存儲到 Document 對象中。

!](http://ww3.sinaimg.cn/large/0...

并且 documents 對象經過 Loader#asDocuments 方法關聯上 spring.profiles.active 屬性,profiles 屬性添加一個定義為 prod 的 Profile,為后面的 Environment 對象添加 Profile 做準備,到這里默認的配置文件 application.properties 加載完畢了,方法又回到了 Loader#load() 上。

有了新添加的 Profile,繼續進入循環,就會通過 Loader#addProfileToEnvironment 方法,為 environment 對象保存激活的 Profile,并且按照之前的邏輯,讀取名為 application-prod.properties 的配置文件,命名方式可以從之前的 Loader#loadForFileExtension 的第462行就可以看出:

Loader#load() 方法讀取了所有配置文件后,執行 Loader#addLoadedPropertySources,將對應屬性源 PropertySource 存儲到 environment 對象中,并且 application-prod.properties 順序先于默認配置文件,就是為了后面程序應用相同名稱配置的時候,優先采用元素位置在前的配置。

至此,所有配置文件上的數據加載完存儲到了與當前上下文關聯的 environment 對象中,將 prod 作為 Active Profile 激活特定環境配置的工作就完成了。

小結

雖然只是探究 Spring Boot 程序如何加載和應用 Profile,但通過這次源碼分析,我們可以發現 SpringBoot 雖簡單易用,但是內部實現邏輯設計是比較復雜的,無論是資源的加載,數據的解析都有專門的組件類去處理,大量使用事件通知和設計模式,在分析源碼時少不了一次又一次的運行斷點,不過這需要我們充分利用DE工具調試功能,在錯綜復雜的代碼中能更準確地定位目標。

推薦閱讀

一文掌握 Spring Boot Profiles

如何優雅關閉 Spring Boot 應用

需要接口管理的你了解一下?

Java 之 Lombok 必知必會

Java 微服務新生代之 Nacos

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/76151.html

相關文章

  • 一文掌握 Spring Boot Profiles

    摘要:需要注意的是必須要使用版本為以上才支持屬性。與格式文件不同,正對不同的,無法在一個文件設置,官方采用命名形式為格式來達成一樣的效果。采用方式添加的是屬于額外激活的,也就是說覆蓋掉外部傳入的指定的。 showImg(https://segmentfault.com/img/remote/1460000019924197?w=1050&h=500); Spring Boot Profile...

    Eidesen 評論0 收藏0
  • [直播視頻] 《Java 微服務實踐 - Spring Boot 系列》限時折扣

    摘要:作為微服務的基礎設施之一,背靠強大的生態社區,支撐技術體系。微服務實踐為系列講座,專題直播節,時長高達小時,包括目前最流行技術,深入源碼分析,授人以漁的方式,幫助初學者深入淺出地掌握,為高階從業人員拋磚引玉。 簡介 目前業界最流行的微服務架構正在或者已被各種規模的互聯網公司廣泛接受和認可,業已成為互聯網開發人員必備技術。無論是互聯網、云計算還是大數據,Java平臺已成為全棧的生態體系,...

    Enlightenment 評論0 收藏0
  • Maven profile整合Spring profile

    摘要:此時可以嘗試或命令打包,安裝包內的文件中占位符已被替換。整合原理項目中一般都會加上可以查看的文件,里面包含定義的值是這樣插件會將或文件中的替換為中對應的值。 在Maven和Spring中,都有profile這個概念。profile是用于區分各種環境的,例如開發環境、測試環境、正式環境等。Maven的profile用于在打包時根據指定環境替換不同環境的配置文件配置,如數據庫配置。Spri...

    用戶84 評論0 收藏0
  • SpringBoot進階教程 | 第一篇:YML多文檔塊實現多環境配置

    摘要:你是否為一個功能多個和多個文件區分不同運行環境配置,經常為這些配置文件的管理而頭疼,現在通過這篇文章,將徹底解決你的煩惱,這篇文篇介紹,怎么通過文件構建多文檔塊,區分不同環境配置,自由切換不同環境啟動項目,一個配置文件搞定。 你是否為SpringBoot一個功能多個yml和多個properties文件區分不同運行環境配置,經常為這些配置文件的管理而頭疼,現在通過這篇文章,將徹底解決你的...

    shmily 評論0 收藏0

發表評論

0條評論

Dionysus_go

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<