SpringCloud入門之應用程序上下文服務(Spring Cloud Context)詳解


構建分布式系統非常復雜且容易出錯。Spring Cloud為最常見的分布式系統模式提供了簡單易用的編程模型,幫助開發人員構建彈性,可靠和協調的應用程序。Spring Cloud構建於Spring Boot之上,使開發人員可以輕松入門並快速提高工作效率。Spring Boot對於如何使用Spring構建應用程序有一個看法:例如它具有常規配置文件的常規位置,以及用於常見管理和監視任務的端點。Spring Cloud建立在此之上,並添加了一些可能系統中所有組件將使用或偶爾需要的功能。

引導應用程序上下文

一個Spring Cloud應用程序通過創建一個“引導”上下文來進行操作,這個上下文是主應用程序的父上下文。開箱即用,負責從外部源加載配置屬性,還解密本地外部配置文件中的屬性。這兩個上下文共享一個Environment,這是任何Spring應用程序的外部屬性的來源。Bootstrap屬性的優先級高,因此默認情況下不能被本地配置覆蓋。

引導上下文使用與主應用程序上下文不同的外部配置約定,因此使用bootstrap.yml application.yml(或.properties)代替引導和主上下文的外部配置。關於配置文件bootstrap.yml與application.yml區別的深入分析詳見SpringCloud入門之常用的配置文件 application.yml和 bootstrap.yml區別

例:

bootstrap.yml
spring:
  application:
    name: order
  cloud:
    config:
      uri: ${SPRING_CONFIG_URI:http://localhost:8888}

如果您的應用程序需要服務器上的特定於應用程序的配置,那么設置spring.application.name(在bootstrap.ymlapplication.yml)中是個好主意。

您可以通過設置spring.cloud.bootstrap.enabled=false(例如在系統屬性中)來完全禁用引導過程。

應用程序上下文層次結構

如果您從SpringApplicationSpringApplicationBuilder構建應用程序上下文,則將Bootstrap上下文添加為該上下文的父級。這是一個Spring的功能,即子上下文從其父進程繼承屬性源和配置文件,因此與不使用Spring Cloud Config構建相同上下文相比,“主”應用程序上下文將包含其他屬性源。額外的資產來源是:

  • 如果您從SpringApplication或SpringApplicationBuilder構建應用程序上下文,則將Bootstrap上下文添加為該上下文的父級。Spring的一個特性是子上下文從其父級繼承屬性源和配置文件,因此與構建沒有Spring Cloud Config的相同上下文相比,“主”應用程序上下文包含其他屬性源。其他財產來源是:

    • “bootstrap”:如果PropertySourceLocators在Bootstrap上下文中找到任何內容,並且它們具有非空屬性,CompositePropertySource則會顯示具有高優先級的可選項一個例子是Spring Cloud Config Server的屬性。
    • “applicationConfig:[classpath:bootstrap.yml]”(以及相關文件,如果Spring配置文件處於活動狀態):如果您有bootstrap.yml(或.properties),則使用這些屬性配置Bootstrap上下文。然后,在設置其父級時,它們將添加到子上下文中。它們的優先級低於application.yml(或.properties)以及作為創建Spring Boot應用程序過程的正常部分添加到子級的任何其他屬性源。有關如何自定義這些屬性源的內容的說明

由於屬性源的排序規則,“引導”條目優先,但請注意,這些條目不包含來自bootstrap.yml的任何數據,它具有非常低的優先級,但可用於設置默認值。

您可以通過簡單地設置您創建的任何ApplicationContext的父上下文來擴展上下文層次結構,例如使用自己的界面,或使用SpringApplicationBuilder方便方法(parent()child()sibling())。引導環境將是您創建自己的最高級祖先的父級。層次結構中的每個上下文都將有自己的“引導”屬性源(可能為空),以避免無意中將值從父級升級到其后代。層次結構中的每個上下文(原則上)也可以具有不同的spring.application.name,因此如果存在配置服務器,則不同的遠程屬性源。普通的Spring應用程序上下文行為規則適用於屬性解析:子環境中的屬性通過名稱和屬性源名稱覆蓋父項中的屬性(如果子級具有與父級名稱相同的屬性源,一個來自父母的孩子不包括在孩子中)。

請注意,SpringApplicationBuilder允許您在整個層次結構中共享Environment,但這不是默認值。因此,兄弟情境尤其不需要具有相同的資料或財產來源,盡管它們與父母共享共同點。

改變引導位置Properties

可以使用spring.cloud.bootstrap.name(默認“引導”)或spring.cloud.bootstrap.location(默認為空)指定bootstrap.yml(或.properties)位置,例如在系統屬性中。這些屬性的行為類似於具有相同名稱的spring.config.*變體,實際上它們用於通過在其Environment中設置這些屬性來設置引導ApplicationContext如果在正在構建的上下文中有活動的配置文件(來自spring.profiles.active或通過Environment API)),則該配置文件中的屬性也將被加載,就像常規的Spring Boot應用程序,例如來自bootstrap-development.properties的“開發”簡介。

覆蓋遠程Properties的值

通過引導上下文添加到應用程序的屬性源通常是“遠程”(例如從配置服務器),並且默認情況下,不能在本地覆蓋,除了在命令行上。如果要允許您的應用程序使用自己的系統屬性或配置文件覆蓋遠程屬性,則遠程屬性源必須通過設置spring.cloud.config.allowOverride=true(在本地設置本身不起作用)授予權限。一旦設置了該標志,就會有一些更精細的設置來控制遠程屬性與系統屬性和應用程序本地配置的位置:spring.cloud.config.overrideNone=true覆蓋任何本地屬性源,spring.cloud.config.overrideSystemProperties=false如果只有系統屬性和env var應該覆蓋遠程設置,而不是本地配置文件。

自定義引導配置

可以通過在org.springframework.cloud.bootstrap.BootstrapConfiguration鍵下添加條目/META-INF/spring.factories來訓練引導上下文來執行任何您喜歡的操作。這是用於創建上下文的Spring @Configuration類的逗號分隔列表。您可以在此處創建要用於自動裝配的主應用程序上下文的任何bean,並且還有ApplicationContextInitializer類型的@Beans的特殊合同。如果要控制啟動順序(默認順序為“最后”),可以使用@Order標記類。

警告
添加自定義BootstrapConfiguration時,請注意,您添加的類不是錯誤的@ComponentScanned到您的“主”應用程序上下文中,可能不需要它們。對於您的@ComponentScan@SpringBootApplication注釋配置類尚未涵蓋的啟動配置類,請使用單獨的包名稱。

引導過程通過將初始化器注入主SpringApplication實例(即正常的Spring Boot啟動順序,無論是作為獨立應用程序運行還是部署在應用程序服務器中)結束。首先,從spring.factories中找到的類創建引導上下文,然后在ApplicationContextInitializer類型的所有@Beans添加到主SpringApplication開始之前。

自定義引導屬性源

引導過程添加的外部配置的默認屬性源是Config Server,但您可以通過將PropertySourceLocator類型的bean添加到引導上下文(通過spring.factories)添加其他源。您可以使用此方法從其他服務器或數據庫中插入其他屬性。

作為一個例子,請考慮以下微不足道的自定義定位器:

@Configuration
public class CustomPropertySourceLocator implements PropertySourceLocator {

    @Override
    public PropertySource<?> locate(Environment environment) {
        return new MapPropertySource("customProperty",
                Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
    }

}

傳入的Environment是要創建的ApplicationContextEnvironment,即為我們提供額外的屬性來源的。它將已經具有正常的Spring Boot提供的資源來源,因此您可以使用它們來定位特定於此Environment的屬性源(例如通過將其綁定在spring.application.name上,如在默認情況下所做的那樣Config Server屬性源定位器)。

如果你在這個類中創建一個jar,然后添加一個META-INF/spring.factories包含:

org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator

那么“customProperty”PropertySource將顯示在其類路徑中包含該jar的任何應用程序中。

環境變化

應用程序將收聽EnvironmentChangeEvent,並以幾種標准方式進行更改(用戶可以以常規方式添加ApplicationListeners附加ApplicationListeners)。當觀察到EnvironmentChangeEvent時,它將有一個已更改的鍵值列表,應用程序將使用以下內容:

  • 重新綁定上下文中的任何@ConfigurationProperties bean

  • logging.level.*中的任何屬性設置記錄器級別

請注意,配置客戶端不會通過默認輪詢查找Environment中的更改,通常我們不建議檢測更改的方法(盡管可以使用@Scheduled注釋進行設置)。如果您有一個擴展的客戶端應用程序,那么最好將EnvironmentChangeEvent廣播到所有實例,而不是讓它們輪詢更改

EnvironmentChangeEvent涵蓋了大量的刷新用例,只要您真的可以更改Environment並發布事件(這些API是公開的,部分內核為Spring)。您可以通過訪問/configprops端點(普通Spring Boot執行器功能)來驗證更改是否綁定到@ConfigurationProperties bean。例如,DataSource可以在運行時更改其maxPoolSize(由Spring Boot創建的默認DataSource是一個@ConfigurationProperties bean),並且動態增加容量。重新綁定@ConfigurationProperties不會覆蓋另一大類用例,您需要更多的控制刷新,並且您需要更改在整個ApplicationContext上是原子的。為了解決這些擔憂,我們有@RefreshScope

刷新范圍

當配置更改時,標有@RefreshScope的Spring @Bean將得到特殊處理。這解決了狀態bean在初始化時只注入配置的問題。例如,如果通過Environment更改數據庫URL時DataSource有開放連接,那么我們可能希望這些連接的持有人能夠完成他們正在做的工作。然后下一次有人從游泳池借用一個連接,他得到一個新的URL。

刷新范圍bean是在使用時初始化的懶惰代理(即當調用一個方法時),並且作用域作為初始值的緩存。要強制bean重新初始化下一個方法調用,您只需要使其緩存條目無效。

RefreshScope是上下文中的一個bean,它有一個公共方法refreshAll()來清除目標緩存中的范圍內的所有bean。還有一個refresh(String)方法可以按名稱刷新單個bean。此功能在/refresh端點(通過HTTP或JMX)中公開。

注意
@RefreshScope(技術上)在@Configuration類上工作,但可能會導致令人驚訝的行為:例如,這並不 意味着該類中定義的所有@Beans本身都是@RefreshScope具體來說,任何取決於這些bean的東西都不能依賴它們在刷新啟動時被更新,除非它本身在@RefreshScope(在其中將重新刷新並重新注入其依賴關系),那么它們將從刷新的@Configuration)重新初始化。

加密和解密

Spring Cloud具有一個用於在本地解密屬性值的Environment預處理器。它遵循與Config Server相同的規則,並通過encrypt.*具有相同的外部配置。因此,您可以使用{cipher}*格式的加密值,只要有一個有效的密鑰,那么在主應用程序上下文獲取Environment之前,它們將被解密。要在應用程序中使用加密功能,您需要在您的類路徑中包含Spring安全性RSA(Maven協調“org.springframework.security:spring-security-rsa”),並且還需要全面強大的JCE擴展你的JVM

如果由於“非法密鑰大小”而導致異常,並且您正在使用Sun的JDK,則需要安裝Java加密擴展(JCE)無限強度管理策略文件。有關詳細信息,請參閱以下鏈接:

將文件解壓縮到JDK / jre / lib / security文件夾(無論您使用的是哪個版本的JRE / JDK x64 / x86)。

端點

端點

對於Spring Boot Actuator應用程序,可以使用一些其他管理端點。您可以使用:

  • POST/actuator/env更新Environment並重新綁定@ConfigurationProperties並記錄水平。
  • /actuator/refresh重新加載引導帶上下文並刷新@RefreshScopebean。
  • /actuator/restart關閉ApplicationContext並重新啟動它(默認情況下禁用)。
  • /actuator/pause/actuator/resume調用的Lifecycle方法(stop()start()ApplicationContext)。
[Note]

如果禁用/actuator/restart端點,那么端點/actuator/pause/actuator/resume端點也將被禁用,因為它們只是一個特例/actuator/restart


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM