Springcloud 引導上下文

? ? ? SpringCloud為我們提供了bootstrap.properties的屬性文件,我們可以在該屬性文件里做我們的服務配置。可是,我們知道SpringBoot已經為我們提供了做服務配置的屬性文件application.properties,那么這兩個配置文件有什么區別呢?在SpringCloud里是否能用bootstrap代替application做服務的配置?要解決這個問題,我們必須先討論一下SpringCloud的引導。

?一、? 官方文檔描述

引導應用程序上下文

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

引導上下文使用與主應用程序上下文不同的外部配置約定,因此使用bootstrap.yml?application.yml(或.properties)代替引導和主上下文的外部配置。例:bootstrap.yml

spring:application:name: foocloud:config:uri: ${SPRING_CONFIG_URI:http://localhost:8888}

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

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

?

二、引導上下文

?1.?關于引導上下文位置

??

? ? ? 這里我們可以發現幾個關鍵的類,其中BootstrapApplicationListener是核心中的核心,可自行查看源碼

? ? ?這個類是一個監聽器,它用于監聽ApplicationEnvironmentPreparedEvent事件,而EventPublishingRunListener在SpringBoot啟動時會觸發該事件。如果不理解的這個類的朋友請務必先了解SpringBoot啟動過程

? ? 2.這個上下文是主應用程序的父上下文

? ? ??這個工作主要分為兩個層面:1.創建上下文引導 2.設置為其為當前程序的父級上下文

? ? ?

?? 1) 我們先看看onApplicationEvent方法,該方法首先讀取spring.cloud.bootstrap.enabled的屬性值如果為false,那么就直接return。這也就是官方文檔里的說明可以用此屬性禁用引導的理由。

? ?2)緊接著它會從當前應用程序SpringApplication試著在所有的ApplicationInitializer中獲取ParentContextApplicationContextInitializer,如果找到的話就把該類下的parent做為引導上下文。

? ?3)如果沒有找到ParentContextApplicationContextInitializer,則通過?bootstrapServiceContext方法來創建引導上下文,其中如下代碼請大家留意下:

    List<String> names = SpringFactoriesLoader.loadFactoryNames(BootstrapConfiguration.class, classLoader);

   ? ? ? 看到SpringFactoriesLoader不用想一定會在META-INF/spring.factoies里找配置的BootstrapConfiguration的進行實例化

? ? ? ? ? ? ?

?4)通過如下代碼創建引導上下文對象:

復制代碼
SpringApplicationBuilder builder = new SpringApplicationBuilder().profiles(environment.getActiveProfiles()).bannerMode(Mode.OFF).environment(bootstrapEnvironment).properties("spring.application.name:" + configName).registerShutdownHook(false).logStartupInfo(false).web(false);if (environment.getPropertySources().contains("refreshArgs")) {// If we are doing a context refresh, really we only want to refresh the// Environment, and there are some toxic listeners (like the// LoggingApplicationListener) that affect global static state, so we need a// way to switch those off.builder.application().setListeners(filterListeners(builder.application().getListeners()));}List<Class<?>> sources = new ArrayList<>();for (String name : names) {Class<?> cls = ClassUtils.resolveClassName(name, null);try {cls.getDeclaredAnnotations();}catch (Exception e) {continue;}sources.add(cls);}AnnotationAwareOrderComparator.sort(sources);builder.sources(sources.toArray(new Class[sources.size()]));final ConfigurableApplicationContext context = builder.run();
復制代碼

  

5)最后通過如下方法設置引導上下文為當前應用程序的上下文:

// Make the bootstrap context a parent of the app contextaddAncestorInitializer(application, context);

?

? ?3. 負責從外部源加載配置屬性,還解密本地外部配置文件中的屬性

??

? ? 開箱即用,理解起來很簡單。通過2.2分析,引導程序在SpringBoot的啟動前就幫我們創建好了,當然也就開箱即用了。

 下面我們看一下spring-cloud-context.jar下的META-INF/spring.factoies文件:

? ??

# AutoConfiguration
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshAutoConfiguration,\
org.springframework.cloud.autoconfigure.RefreshEndpointAutoConfiguration,\
org.springframework.cloud.autoconfigure.LifecycleMvcEndpointAutoConfiguration# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener# Bootstrap components
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration,\
org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration,\
org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration
View Code

?我們來看一下 ?BootstrapConfiguration下面配置的引導程序類:

   ?org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration:這個類主要解析加載外部化配置屬性

   ?org.springframework.cloud.bootstrap.encrypt.EncryptionBootstrapConfiguration:主要配置文件中前綴為{cipher}的相關解密,熟悉spring-boot-starter-security在springcloud應用的朋友一定不陌生

   ?org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration:主要是監聽EnvironmentChangeEvent事件用于刷新@ConfigurationProperties標記的配置

   ?org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration:主要解析配置文件中的${}占位符

?

?4. 這兩個上下文共享一個Environment

? ? ? ?既然引導上下文為當前主程序的父級上下文,那么就可以確定他們共享Environment,至于為什么請閱讀文章第一部分

?5. BootStrap屬性的優先級高,因此默認情況下不能被本地配置覆蓋

? ? ??對于引導程序bootstrap.yml比application.yml優先級更高,更不可能被application.yml文件里的所覆蓋

?三、總結

  1)引導程序上下文在prepareEnvironment的階段就會被創建,創建時會讀取bootstrap.properties|yml 在內容作為引導配置, 因此bootstrap優先于application加載。引導程序非常類似于bios,而bootstrap.application就相當于設置bios的相關參數

  2)boostrap的屬性文件在以下情景下會使用:

    配置中心:config-server里請用bootstrap屬性文件

    ? 解密屬性文件時,最好使用bootstrap屬性文件

    需要自定義引導程序時使用bootstrap屬性文件,主要一定不要被我們主程序掃描到

  3)application會覆蓋bootstrap中的非引導配置,因此不建議兩種類型配置文件同時存在。簡單粗暴的做法是在springcloud應用中用bootstrap屬性文件代替application一統江湖嘛,畢竟Envrionment是共享的。

  4) ?在閱讀官方文檔時,一定要結合源代碼深入分析,才能更好的理解其用意

轉載于:https://www.cnblogs.com/whx7762/p/11232019.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/448176.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/448176.shtml
英文地址,請注明出處:http://en.pswp.cn/news/448176.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Springboot 項目中過濾器的使用

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 編寫過濾器類&#xff1a; package gentle;import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.se…

C++ 中 new 操作符內幕:new operator、operator new、placement new

一、new 操作符&#xff08;new operator&#xff09; 人們有時好像喜歡有意使C語言的術語難以理解。比方說new操作符&#xff08;new operator&#xff09;和operator new的差別。 當你寫這種代碼&#xff1a; string *ps new string("Memory Management");你使…

Flask-1-05-CookieSession

接下來我會演示一下設置Cookie 讀取Cookie 刪除Cookie&#xff0c;以及添加Cookie的原理 接下來我們分別定義3個視圖為 set_cookie、get_cookie、del_cookie # coding:utf-8from flask import Flask, make_response, requestapp Flask(__name__)app.route("/set_cookie&q…

18個不可不知的有用潛規則

人情世故是我們日常生活中積累的約定俗成的行為規則&#xff0c;屬于社會知識的范疇。這些知識大半來源于與不同人群的社會交際&#xff0c;也來源于社會沖突與社會發展。在有專業知識與技能的情況下&#xff0c;人情世故能夠幫助我們個人緩和與其他人之間的緊張度&#xff0c;…

解決跨域問題:No ‘Access-Control-Allow-Origin‘ header is present on the requested resource.

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 PS&#xff1a;如果遇到 這個問題 Request header field Content-Type is not allowed by Access-Control-Allow-Headers&#xff0c;解…

錯誤代碼:0xc000007b 解決思路

三維電子沙盤項目&#xff1a; 現場環境部署時&#xff0c;二維平臺和模型在實際部署中遇到了0xc000007b的問題&#xff0c;網上很多說是DX的問題&#xff0c;但并不能解決。 之前在編譯OpenDDS時也遇到過類似的問題&#xff0c;是在不同版本的OpenDDS的動態庫混用時遇到的&a…

上傳本地項目到git

1、到需要上傳的文件夾下&#xff0c;打開gitbase 2、git init 3、git add . 4、git commit -m init 5、驗證權限 首先在Git Bash中輸入:ssh-keygen -t rsa -C "youremailxxx.com" 然后一路回車,這個會在當前用戶文件夾下&#xff0c;生成.ssh 文件夾&#xff0c;里邊…

vue 設置全局變量、指定請求的 baseurl

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 安裝 axios&#xff1a; npm install axios --save-dev 2. 新建一個 Base.vue 文件&#xff0c;書寫內容如下&#xff1a; <sc…

解決這九種困擾 可以讓你每天精神百倍

晚上睡眠是人體最好的休息方式&#xff0c;人體的很多癥狀都會在充足的睡眠后得到緩解&#xff0c;良好的睡眠比世界上的任何藥都靈&#xff0c;而現代社會&#xff0c;“一覺睡到自然醒”已是很多人可望而不可及的了。我經過多年的仔細觀察&#xff0c;發現只要是在早晨醒來后…

基于java的數據結構學習——泛型動態數組的封裝

public class Array<E> {private E[] data;private int size;// 構造函數public Array(int Capacity){data (E[])new Object[Capacity];size 0;}// 默認構造函數public Array(){this(10);}// 判斷數組是否已滿public boolean isFull(){return size data.length;}// 判…

POJ1207-The 3n + 1 problem

http://poj.org/problem?id1207 注意輸入兩個數的大小&#xff0c;水。。。 #include <stdio.h> int main(void) {int a,b,m,count,i,max;while(scanf("%d%d",&a,&b)!EOF){printf("%d %d ",a,b);if(a>b){ma;ab;bm;}max0;for(ia;i<b;i…

解決:vue.esm.js?efeb:591 [Vue warn]: Do not use built-in or reserved HTML elements as component id: me

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 報錯如題&#xff1a; vue.esm.js?efeb:591 [Vue warn]: Do not use built-in or reserved HTML elements as component id: menu …

JetBrains 系列軟件漢化包

Android Studio 3.0-3.1 漢化包 CLion 2018.1 漢化包 GoLand 2017.3.2-2018.1 漢化包 IntelliJ IDEA 2017.3-2018.1 漢化包 PhpStorm 2017.3-2018.1 漢化包 PyCharm 2017.3-2018.1 漢化包 RubyMine 2017.3.2-2018.1 漢化包 WebStorm 2017.3-2018.1 漢化包 下載完畢后&#xff…

JAXP進行DOM和SAX解析

1.常用XML的解析方式&#xff1a;DOM和SAX 1&#xff09;DOM思想&#xff1a;將整個XML加載內存中&#xff0c;形成文檔對象&#xff0c;所以對XML操作都對內存中文檔對象進行。 2&#xff09;SAX思想&#xff1a;一邊解析&#xff0c;一邊處理&#xff0c;一邊釋放內存資源---…

VScode 格式化代碼快捷鍵、修改快捷鍵

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 1. 請看仔細快捷鍵是&#xff1a; shift alt F // 我是從 eclipse 轉的 idea &#xff0c;現在再用 vscode , 一直條件反射的按的 c…

信息學競賽的常數優化、常見問題、代碼風格相關

在查std::ios::sync_with_stdio(false);有關信息時&#xff0c;看到https://blog.csdn.net/qq_33583069/article/details/53086992 這篇博客&#xff0c;對其中一些問題比較感興趣&#xff0c;整理了下相關資料&#xff1a; isdigit()https://blog.csdn.net/cupidove/article/d…

TCP報文格式詳解

TCP協議只定義了一種報文格式 建立、拆除連接、傳輸數據使用同樣的報文 TCP報文格式 TCP報文段首部&#xff08;20個字節&#xff09; 源端口和目的端口&#xff1a;各占2個字節&#xff0c;16比特的端口號加上32比特的IP地址&#xff0c;共同構成相當于傳輸層服務訪問點的地址…

Vue 生命周期中 mounted( ) 和 created( ) 的區別

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 一、什么是生命周期&#xff1f; 用通俗的語言來說&#xff0c;就是Vue中實例或者組件從創建到消滅中間經過的一系列過程。雖然不太嚴謹…

科目三考試

馬上要考大路了&#xff0c;考科目三考試必須做到什么事啊&#xff1f; 2012-5-30 8:46:23檢舉  注意事項   1、上車后確認車上電腦信息后&#xff0c;關好車門&#xff0c;系好安全帶&#xff0c;打左轉向燈起步。   2、直線行駛路段必須使用二檔行駛。否則將被判…

基于java的數據結構學習——數組實現的棧以及簡單應用

棧 Stack 棧是一種線性結構相比數組&#xff0c;棧對應的操作是數組的子集只能從一端添加元素&#xff0c;也只能從一端取出元素這一端稱為棧頂棧是一種后進先出的數據結構 棧的應用 無處不在的Undo操作&#xff08;撤銷&#xff09;括號匹配&#xff08;編譯器&#xff09;程…