擴充套件 Spring Cloud

工程 | Ramnivas Laddad | 2014年8月5日 | ...

Spring Cloud 最有趣的特性之一是其可擴充套件性。您可以擴充套件它以支援其他雲、增強已支援的雲、支援新服務、新服務聯結器——所有這些都無需修改 Spring Cloud 程式碼本身。在本部落格中,我們將探討此功能。如果您還沒有這樣做,請閱讀本系列的第一篇第二篇部落格,以獲取足夠的背景知識。

可擴充套件性的三個軸

Spring Cloud 在三個正交方向上提供了可擴充套件性。您可以沿其中一個方向擴充套件它,而正交性確保您能繼續受益於其他方向。

  1. 雲平臺:雖然 Spring Cloud 支援 Cloud Foundry、Heroku 和本地配置雲(用於在類似雲的環境中進行本地測試),但您不受這些選擇的限制。您可以新增自己的雲平臺,並利用 Spring Cloud 的其他功能,例如 Spring Java Config。

  2. 雲服務:雲平臺提供各種服務,從關係型資料庫到訊息傳遞。每個雲平臺提供的服務差異很大,即使是同一平臺的多個安裝也是如此。對於 PaaS 產品(如 Cloud Foundry)來說尤其如此,Cloud Foundry 的私有例項往往具有特定於每個安裝的服務。Spring Cloud 提供了一種簡單的方法來擴充套件其核心產品之外的服務。就像雲平臺的可擴充套件性一樣,您無需更改 Spring Cloud 程式碼即可將其擴充套件到新服務,並且您可以繼續利用其他部分。

  3. 框架:Spring Cloud 目前透過 spring-service-connector 模組支援 Spring 框架。但是,除了該模組之外,Spring Cloud 中的任何部分都不依賴於 Spring。因此,您應該能夠使用任何基於 JVM 的框架的其他部分,或者透過新增新模組來擴充套件它以支援某個框架。

上一篇部落格中,我們探討了如何使用 CloudFactoryCloud 以程式設計方式使用 Spring Cloud。在可擴充套件性方面,您將不會使用這些,而是將在核心模組中實現其他型別。讓我們來看看它們。

雲平臺可擴充套件性

要將 Spring Cloud 擴充套件到新的雲平臺,您需要熟悉的主要型別是 CloudConnector,它是一個簡單的三方法介面

public interface CloudConnector {
	boolean isInMatchingCloud();
	ApplicationInstanceInfo getApplicationInstanceInfo();
	List<ServiceInfo> getServiceInfos();
}

isInMatchingCloud() 方法應該檢查其環境以確定它是否在正確的環境中執行。例如,Cloud Foundry 聯結器檢查 VCAP_APPLICATION 環境變數是否存在,而 Heroku 聯結器則檢查 DYNO 環境變數是否存在。getApplicationInstanceInfo() 方法返回當前應用程式例項的資訊(應用程式名稱、主機、埠和應用程式屬性)。最有趣的方法 getServiceInfos() 返回一個列表,其中每個元素包含足夠的資訊,以便應用程式知道如何連線到每個服務。每個 ServiceInfo 物件中包含的確切資訊取決於每個實現(ServiceInfo 本身只定義一個方法:getId())。

建立 CloudConnector 的實現後,您需要讓 Spring Cloud 瞭解它。對於所有擴充套件點,Spring Cloud 使用基於 ServiceLoader 的統一機制。應用於 Spring Cloud 的平臺可擴充套件性,它歸結為包含一個名為 /META-INF/services/org.springframework.cloud.CloudConnector 的檔案,其中包含一個帶有實現類的完全限定名稱的條目。通常,您會將此檔案與您的實現和支援類捆綁在一起。然後,應用程式所要做的就是將此 jar 包含在類路徑中。

服務可擴充套件性

ServiceInfoCreator 介面提供了一個擴充套件點,用於處理新服務。

public interface ServiceInfoCreator<SI extends ServiceInfo, SD> {
    public boolean accept(SD serviceData);
    public SI createServiceInfo(SD serviceData);
}

泛型引數 SI 定義了它將建立的 ServiceInfo 型別,而 SD 引數定義了它可以使用的原始服務資料型別。原始服務資料型別取決於雲平臺。例如,在 Cloud Foundry 中,它將是基於 VCAP_SERVICES 環境變數的 Map,而在 Heroku 中,它將是包含服務特定環境變數及其值的對。由於原始資料型別取決於平臺,因此 ServiceInfoCreator 的實現也取決於平臺。accept() 方法檢查服務資料並確定它是否可以處理它。例如,它可以檢視 URL 方案並確定它是否可以消費該服務資料。如果可以,createServiceInfo() 必須返回一個 ServiceInfo 物件。如果它是一個全新的服務,您可能還需要為它實現 ServiceInfo,否則您可以使用現有的服務。

一旦您實現了 ServiceInfoCreator,您將不得不讓 Spring Cloud 知道它。這遵循了與前面討論的雲平臺可擴充套件性相同的思路。在這種情況下,您使用的檔名取決於 CloudConnector。對於 Cloud Foundry,它是 /META-INF/services/org.springframework.cloud.cloudfoundry.CloudFoundryServiceInfoCreator(理論上,CloudConnector 實現可能決定使用其他擴充套件機制,但 Spring Cloud 不推薦這樣做)。

正如上一篇部落格中討論的,雲應用開發人員可能會決定直接使用 ServiceInfo 物件。因此,如果您只實現一個 ServiceInfoCreator,您就已經提供了一些好處。然而,許多專注於開發應用程式的開發人員可能不喜歡使用原始的 ServiceInfo 物件,因此您還需要實現下一個擴充套件。

框架可擴充套件性

最後一個擴充套件點是 ServiceConnectorCreator。它的作用是將 ServiceInfo 轉換為適合應用程式使用的框架的服務聯結器。例如,它可以將 MysqlServiceInfo 轉換為 DataSource 物件。Spring Cloud 開箱即用地支援 DataSource 以及一些 Spring DataSpring AMQP 型別的聯結器。如果您希望將 Spring Cloud 擴充套件到其他框架,或者如果您想支援 Spring Cloud 尚未直接支援的其他 Spring Data 型別(如 Neo4J、Elasticsearch、Cassandra)或 Spring 相容型別(如 S3),這就是您需要的擴充套件點。

public interface ServiceConnectorCreator<SC, SI extends ServiceInfo> {
    SC create(SI serviceInfo, ServiceConnectorConfig serviceConnectorConfig);
    ...
}

還有幾個方法;但是,您通常會擴充套件負責實現這些方法的 AbstractServiceConnectorCreator

ServiceConnectorCreatorSC 泛型引數繫結到它將建立的聯結器型別,例如 DataSource,而 SI 引數表示它可以使用的 ServiceInfo 型別。

create() 方法提供一個 ServiceInfo 物件和一個配置物件,該物件攜帶服務特定的資訊,例如連線池引數。它需要使用這些引數來建立適當的聯結器。

一旦實現完成,只需將其放入名為 /META-INF/services/org.springframework.cloud.service.ServiceConnectorCreator 的檔案中。Spring Cloud 將使用前面描述的 Service Loader 機制。

總結

如您所見,Spring Cloud 在雲平臺、服務和框架軸上提供了強大的可擴充套件性。下次,當您遇到這些新型別時,您應該能夠擴充套件 Spring Cloud 以便與它們一起工作。如果您將您的擴充套件開源,請告訴我們,以便我們可以展示它,讓其他人受益。如果它是一個足夠常見的擴充套件,請考慮提交拉取請求。

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

VMware 提供培訓和認證,助您加速進步。

瞭解更多

獲得支援

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位制檔案,只需一份簡單的訂閱。

瞭解更多

即將舉行的活動

檢視 Spring 社群所有即將舉行的活動。

檢視所有