将 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 社区所有即将举行的活动。

查看所有