本系列為之前系列的整理重啟版,隨著專案的發展以及專案中的使用,之前系列裡面很多東西發生了變化,並且還有一些東西之前系列並沒有提到,所以重啟這個系列重新整理下,歡迎各位留言交流,謝謝!~
在理解 Spring Cloud 之前,我們先了解下 Spring 框架、Spring Boot、Spring Cloud 這三者的關係,從一個簡單的 Bean,是如何發展出一個具有微服務特性的 Spring Cloud 的呢?
Spring bean 是 Spring 框架在執行時管理的物件。Spring bean 是任何Spring應用程式的基本構建塊。你編寫的大多數應用程式邏輯程式碼都將放在Spring bean 中。之後我們就用 Bean 來簡稱 Spring bean。
BeanFactory 是 Spring 容器的核心,是一個管理著所有 Bean 的容器。通常情況下,BeanFactory 的實現是使用懶載入的方式,這意味著 Bean 只有在我們通過 getBean()
方法直接呼叫獲取它們時才進行例項化。
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 啟動之後例項化。
在 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.factories
和 application.properties
),在此基礎上進而實現瞭如下功能:
- 內建 servlet 容器,提供了容器的統一抽象,即
WebServer
。目前包括:Tomcat(TomcatWebServer
),Jetty(JettyWebServer
),Undertow(UndertowWebServer
),Netty(NettyWebServer
) - 不同 servlet 容器的配置都可以用相同的 key 在 application.yml 中配置。例如暴露埠不用再在不同的 servlet 容器中配置,而是直接在 application.yml 中配置
server.port
即可。 - 不再需要構造 war 包部署到 servlet 容器中,而是直接打包成一個 jar 包直接執行。
- 使用者不用關心 ApplicationContext 的建立與管理,而是可以直接使用。
- 只存在一個 ClassLoader,而不是像 servlet 容器那樣有獨立的 ClassLoader
Spring Cloud 在 Spring Boot 的基礎上,增加微服務相關元件的介面與實現,不同的 Spring Cloud 體系元件介面與實現不同。但是公共的元件介面在 spring-cloud-commons 這個專案中,其中關於微服務元件的介面包括:
- 服務註冊介面
- 服務發現介面
- 負載均衡介面
- 斷路器介面
實現這些介面的元件,會基於 Spring Cloud 的 NamedContextFactory
,對於不同微服務的呼叫或者控制,以微服務名稱區分,產生不同的子 ApplicationContext。對於這個 NamedContextFactory
,我們這個系列會專門有一節進行分析。
我們這一節梳理清楚了從 Bean 到 BeanFactory,在 BeanFactory 基礎上封裝的 ApplicationContext,以及主要基於註解的 ApplicationContext 以及 Spring factory SPI 的 Spring Boot,以及在 Spring Boot 基礎上增加微服務抽象的 Spring Cloud 的這一系列關係。接下來我們會詳細分析下 Spring Cloud 中很重要的抽象 - NamedContextFactory
微信搜尋“我的程式設計喵”關注公眾號,每日一刷,輕鬆提升技術,斬獲各種offer: