SpringCloud升級之路2020.0.x版-7.從Bean到SpringCloud

乾貨滿滿張雜湊發表於2021-08-09

image

本系列為之前系列的整理重啟版,隨著專案的發展以及專案中的使用,之前系列裡面很多東西發生了變化,並且還有一些東西之前系列並沒有提到,所以重啟這個系列重新整理下,歡迎各位留言交流,謝謝!~

在理解 Spring Cloud 之前,我們先了解下 Spring 框架、Spring Boot、Spring Cloud 這三者的關係,從一個簡單的 Bean,是如何發展出一個具有微服務特性的 Spring Cloud 的呢?

image

Spring bean 是 Spring 框架在執行時管理的物件。Spring bean 是任何Spring應用程式的基本構建塊。你編寫的大多數應用程式邏輯程式碼都將放在Spring bean 中。之後我們就用 Bean 來簡稱 Spring bean

image

BeanFactory 是 Spring 容器的核心,是一個管理著所有 Bean 的容器。通常情況下,BeanFactory 的實現是使用懶載入的方式,這意味著 Bean 只有在我們通過 getBean() 方法直接呼叫獲取它們時才進行例項化

image

ApplicationContext 在 BeanFactory 的基礎上,增加了:

  • 資源定位與載入,基於 ResourcePatternResolver(其實就是帶萬用字元的 ResourceLoader),用來定位並載入各種檔案或者網路資源
  • 所處環境,基於 EnvironmentCapable。每個 ApplicationContext 都是有 Environment 的,這個 Environment,包括 Profile 定義還有 Properties。Profile 配置是一個被命名的、bean 定義的邏輯組,這些 bean 只有在給定的 profile 配置啟用時才會註冊到容器。Properties 是 Spring 的屬性組,這些屬性可能來源於 properties 檔案、JVM properties、system環境變數、JNDI、servlet context parameters 上下文引數、專門的 properties 物件,Maps 等等。
  • Bean 的初始化
  • 更加完整的 Bean 生命週期,包括 BeanPostProcessor 以及 BeanFactoryPostProcessor 的各種處理
  • 國際化,核心類MessageSource
  • 事件釋出,基於 ApplicationEventPublisher:將 ApplicationEvent 或者其他型別的事件,發給所有的 Listener

可以理解為 ApplicationContext 內部包含了一個 BeanFactory,並增加了其他的元件,實現了更豐富的功能,並且,與 BeanFactory 懶載入的方式不同,它是預載入,所以,每一個 Bean 都在 ApplicationContext 啟動之後例項化。

image

在 ApplicationContext 的基礎上,Spring 框架引入了很多特性。其中最常見的就是 Spring Web 程式。在過去,Spring Web 應用程式被嵌入到 servlet 容器中執行,大多數的企業應用都是在 servlet 容器上配置並部署執行的。這對於開發人員來說,又增加了關於對應 servlet 容器的學習曲線,這包括:

  • web.xml 和其他面向 servlet 的配置概念
  • .war 檔案目錄結構
  • 不同容器的特定配置(例如暴露埠配置,執行緒配置等等)
  • 複雜的類載入層次
  • 在應用程式之外配置的監控管理相關設施
  • 日誌相關
  • 應用程式上下文配置等等

以上配置不同容器並不統一,開發者需要在知道 spring 相關配置的基礎上,還要了解容器這些配置特性。這些複雜的配置特性導致學習門檻變高,並且隨著技術發展掌握 Servlet 原理的開發者越來越少了。在企業應用開發的時候,應用程式框架越簡單,開發人員就越有可能採用該框架。於是,Mike Youngstrom 提出 Improved support for 'containerless' web application architectures,意圖通過內建 Servlet 容器以及預設載入某些類組成特定的 ApplicationContext,來簡化 Spring 應用開發的配置。

Spring Boot,在 ApplicationContext 的基礎上,實現了 Spring Boot 特有的 ApplicationContext,並通過新增不同 ApplicationEvent 的 Listener 實現了特有的生命週期配置SPI 載入機制(spring.factoriesapplication.properties),在此基礎上進而實現瞭如下功能:

  1. 內建 servlet 容器,提供了容器的統一抽象,即 WebServer。目前包括:Tomcat(TomcatWebServer),Jetty(JettyWebServer),Undertow(UndertowWebServer),Netty(NettyWebServer)
  2. 不同 servlet 容器的配置都可以用相同的 key 在 application.yml 中配置。例如暴露埠不用再在不同的 servlet 容器中配置,而是直接在 application.yml 中配置 server.port 即可。
  3. 不再需要構造 war 包部署到 servlet 容器中,而是直接打包成一個 jar 包直接執行。
  4. 使用者不用關心 ApplicationContext 的建立與管理,而是可以直接使用。
  5. 只存在一個 ClassLoader,而不是像 servlet 容器那樣有獨立的 ClassLoader

image

Spring Cloud 在 Spring Boot 的基礎上,增加微服務相關元件的介面與實現,不同的 Spring Cloud 體系元件介面與實現不同。但是公共的元件介面在 spring-cloud-commons 這個專案中,其中關於微服務元件的介面包括:

  • 服務註冊介面
  • 服務發現介面
  • 負載均衡介面
  • 斷路器介面

實現這些介面的元件,會基於 Spring Cloud 的 NamedContextFactory,對於不同微服務的呼叫或者控制,以微服務名稱區分,產生不同的子 ApplicationContext。對於這個 NamedContextFactory,我們這個系列會專門有一節進行分析。

image

我們這一節梳理清楚了從 Bean 到 BeanFactory,在 BeanFactory 基礎上封裝的 ApplicationContext,以及主要基於註解的 ApplicationContext 以及 Spring factory SPI 的 Spring Boot,以及在 Spring Boot 基礎上增加微服務抽象的 Spring Cloud 的這一系列關係。接下來我們會詳細分析下 Spring Cloud 中很重要的抽象 - NamedContextFactory

微信搜尋“我的程式設計喵”關注公眾號,每日一刷,輕鬆提升技術,斬獲各種offer

image

相關文章