使用 Cloud Foundry 服務與 Spring:第 2 部分 - 自動重新配置

工程 | Ramnivas Laddad | 2011 年 11 月 04 日 | ...

如果您觀看了 Cloud Foundry 發表會的影片,您會看到我們部署了從 Spring Web Flow 範例下載的 Spring Travel 應用程式,將 MySQL 服務繫結到它,並且在 STS 中將應用程式拖放到 Cloud Foundry 伺服器,而無需對應用程式本身進行任何更改。這怎麼可能,因為應用程式配置為使用本地資料庫?這就是自動重新配置發揮作用的地方。

Cloud Foundry 致力於保持您的初始投資較低。除了金錢之外,真正的投資來自開發人員在入門時所花費的時間。當您想要開始使用 Cloud Foundry 時,自動重新配置是一種減少初始投資的機制。在這篇部落格中,我們將探討它如何與 Spring 應用程式一起運作(grails 應用程式使用相同的底層機制,因此行為相同)。

利用依賴注入進行自動重新配置

您的應用程式包含業務邏輯以及與資料庫和訊息傳遞等服務的互動。在典型的 Spring 應用程式中,您可以利用依賴注入 (DI) 為每個使用的服務建立 bean,並將這些 bean 注入到需要存取這些服務的其他 bean 中。

讓我們看看一個典型的 Spring 應用程式,它使用一個關聯式資料庫,該資料庫將具有一個資料來源 bean,定義如下:


<bean class="org.apache.commons.dbcp.BasicDataSource" id="dataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/inventory-db"/>
    <property name="username" value="myuser"/>
    <property name="password" value="mypass"/>
</bean>

我們可以將使用者名稱和密碼等屬性外部化到一個單獨的檔案中,但我們嵌入值以專注於自動重新配置機制。

然後,這個 bean 可以被注入到其他 bean 中(在本例中,注入到 JPA 實體管理器中):


<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
    <property name="persistenceUnitName" value="persistenceUnit"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

我們可以做出一個簡單的觀察:資料庫 URL 指向 localhost 上的資料庫,使用者名稱設定為 "myuser",密碼設定為 "mypass"。當您將此應用程式推送到 Cloud Foundry 並繫結 MySQL 或 Postgres 服務時,該服務的 URL 不會是 jdbc:mysql://127.0.0.1:3306/inventory-db,並且使用者名稱或密碼也不會那麼簡單!因此,如果沒有額外的機制,這樣的應用程式將在啟動時失敗。這就是自動重新配置機制發揮作用的地方。自動重新配置機制利用 DI 來檢查 Spring 應用程式上下文,尋找與服務對應的 bean,並使用基於繫結到應用程式的服務所建立的 bean 來替換每個服務。結果是使用者應用程式在本地部署和 Cloud Foundry 中無需任何更改即可工作。

下表顯示了自動重新配置尋找重新配置的 bean 類型。

服務類型取代的 bean 類型
Mysql, Postgresjavax.sql.DataSource
Redisorg.springframework.data.redis.connection.RedisConnectionFactory
MongoDBorg.springframework.data.document.mongodb.MongoDbFactory
RabbitMQorg.springframework.amqp.rabbit.connection.ConnectionFactory

自動重新配置背後的底層機制使用一個 BeanFactoryPostProcessor,它在建立 bean 之前檢查應用程式上下文,並使用基於繫結到應用程式的服務的等效 bean 替換現有的匹配類型 bean。對於關聯式資料庫,它還會重新配置 JPA 實體管理器 factory 或 Hibernate session factory,以調整正在使用的方言。

當您的應用程式在部署過程中被暫存時,Cloud Foundry 將進行兩項修改:

  1. 它會將一個額外的 jar 添加到您的應用程式中,其中包含 BeanFactoryPostProcessor 和相關資源。請注意,用於自動重新配置的 jar 也附帶一個版本的 cloudfoundry-runtime。但是,這些類別透過陰影機制重新定位到不同的套件。這允許您的應用程式使用不同版本的 cloudfoundry-runtime 而不會發生任何衝突。
  2. 它將修改 web.xml 以更新構成 Spring 應用程式上下文的檔案,以將 BeanFactoryPostProcessor 添加到其中。

限制

服務的自動重新配置僅在以下條件下有效:
  1. 對於給定的服務類型,只能存在一個服務。例如,您只能將一個關聯式資料庫服務(MySQL 或 Postgres)繫結到一個應用程式。
  2. 對於匹配的類型,只能存在一個 bean。例如,您的應用程式上下文中只能有一個 DataSource bean。

如果應用程式不遵守這些限制,則不會發生自動重新配置機制。在這些情況下,您需要使用下一個部落格中描述的 <cloud> 命名空間,無論是否使用 Spring 3.1 設定檔支援。

自動重新配置機制期望典型的 Spring 應用程式。如果您的應用程式上下文很複雜,則可能無法運作。在這種情況下,您可以選擇退出自動重新配置,我們將在接下來的部分中描述。

選擇退出自動重新配置

在某些情況下,您可能想要選擇退出自動重新配置。例如,您可能有一個不應繫結到 Cloud Foundry 服務的記憶體關聯式資料庫。Cloud Foundry 提供了幾種退出自動重新配置機制的方法。
  1. 部署應用程式時,選擇框架為 "JavaWeb"。這會將您的應用程式視為非 Spring 應用程式。這是一種硬退出,因為您的應用程式將保持不變(不會將 jar 添加到您的應用程式,並且 web.xml 將保持不變)。這也意味著本部落格系列稍後討論的設定檔功能將不適用於此類應用程式。
  2. 使用任何建立表示服務的 bean 的 <cloud> 元素。這目前包括 <cloud:data-source><cloud:mongo-db-factory><cloud:rabbit-connection-factory><cloud:redis-connection-factory><cloud:service-scan>。如果應用程式直接包含基於這些命名空間元素的底層類型的 bean(例如 CloudMongoDbFactoryBean),則退出將生效。Cloud Foundry 使用此機制選擇退出,因為應用程式要么想要具有自動重新配置行為,要么只是完全控制服務建立。我們認為自動重新配置某些服務和手動執行其他服務沒有價值。

結論

Cloud Foundry 中的自動重新配置功能是入門的好方法。隨著您的應用程式成熟或您需要繫結到多個服務,您可能需要更好地控制服務連線物件。這就是 <cloud> 命名空間支援發揮作用的地方。在本系列的下一篇部落格中,Thomas Risberg 將解釋如何使用它。Thomas,交給你了。

取得 Spring 電子報

透過 Spring 電子報保持聯繫

訂閱

領先一步

VMware 提供培訓和認證,以加速您的進展。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進位檔案。

了解更多

即將舉行的活動

查看 Spring 社群中所有即將舉行的活動。

查看所有