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

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

如果您觀看了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://: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 指向本地主機上的資料庫,使用者名稱設定為“myuser”,密碼設定為“mypass”。當您將此應用程式推送到 Cloud Foundry 並繫結 MySQL 或 Postgres 服務時,該服務的 URL 將不會是 jdbc:mysql://: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 實體管理器工廠或 Hibernate 會話工廠,以調整所使用的方言。

當您的應用程式在部署過程中進行 staging 時,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>。如果應用程式直接包含基於這些名稱空間元素的底層型別(例如 CloudMongoDbFactoryBean)的 bean,則將生效選擇退出。Cloud Foundry 使用此機制選擇退出,因為應用程式要麼想要自動重新配置行為,要麼完全控制服務建立。我們認為自動重新配置某些服務而手動處理其他服務沒有價值。

結論

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

獲取 Spring 新聞通訊

透過 Spring 新聞通訊保持聯絡

訂閱

領先一步

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

瞭解更多

獲得支援

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

瞭解更多

即將舉行的活動

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

檢視所有