使用 Cloud Foundry 服务与 Spring:第二部分 - 自动重新配置

工程 | 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://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 实体管理器工厂或 Hibernate 会话工厂以调整所使用的方言。

在部署过程中对您的应用程序进行分阶段处理时,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 社区中所有即将举行的活动。

查看全部