【问题标题】:Using spring cloud namespace and two DataSources使用 spring cloud 命名空间和两个 DataSource
【发布时间】:2015-08-29 22:29:06
【问题描述】:

我有一个 Spring Integration WAR 组件,我正在更新它以在私有 PCF 中运行。我在应用程序中定义了两个 DataSource 和一个 RabbitMQ 连接工厂。

我看到 Thomas Risberg 的一篇关于使用云命名空间和同时处理多个服务的文章 - https://spring.io/blog/2011/11/09/using-cloud-foundry-services-with-spring-part-3-the-cloud-namespace。这是通过使用@Autowired 和@Qualifier 注释来处理的。

我想知道当我们没有 @Autowired 和 @Qualifier 注释时如何实现这一点,例如将 DataSource 连接到 JdbcTemplate。这里我们无法指定@Qualifier 注解。

我的应用程序是基于 Spring XML 配置的。我确实有能力在其中一个数据源上使用 @Autowired 和 @Qualifier 注释,但另一个是 JPA 实体管理器。见代码 sn-p。

非常感谢任何帮助。

    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="persistenceUnitName" value="activity-monitor" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="jpaProperties">
            <value>
                hibernate.format_sql=true
            </value>
        </property>
    </bean>

    <beans profile="cloud">
        <cloud:data-source id="dataSource" service-name="actmon-db-service" />
    </beans>

Java 构建包:java_buildpack_offline java-buildpack-offline-v2.4.zip Spring Auto-reconfiguration version 1.4.0.

更新:这是两个数据源的完整配置,包括使用 DAO 从数据源加载属性的 PropertySourcesPlaceholderConfigurer。

<bean id="cic.application.ppc" class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer"> 
    <property name="properties" ref="cic.application.properties"/> 
    <property name="locations" ref="cic.application.propertyLocations"/> 
</bean>

<bean id="cic.application.properties" class="java.util.Properties">
    <constructor-arg value="#{cicPropertiesService.properties}"></constructor-arg>
</bean>

<bean id="cic.properties.propertiesService" name="cicPropertiesService"
    class="com.emc.it.eis.properties.service.DefaultPropertiesService">
    <constructor-arg index="0"
        ref="cic.properties.propertiesDao" />
</bean>

<bean id="cic.properties.propertiesDao" class="com.emc.it.eis.properties.dao.JdbcPropertiesDao">
    <constructor-arg ref="cic.properties.dataSource" />
</bean>

<beans profile="default">
    <jee:jndi-lookup id="cic.properties.dataSource"
        jndi-name="jdbc/intdb" />
</beans>

<beans profile="cloud">
    <cloud:data-source id="cic.properties.dataSource" service-name="oracle-cicadm-db-service" />
</beans>

<beans>
    <bean id="entityManagerFactory"
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="actmonDataSource" />
        <property name="persistenceUnitName" value="activity-monitor" />
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
        <property name="jpaProperties">
            <value>
                hibernate.format_sql=true
            </value>
        </property>
    </bean>

    <bean id="transactionManager"
        class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
    </bean>
</beans>

<beans profile="default">
    <jee:jndi-lookup id="dataSource"
        jndi-name="jdbc/actmon" />
</beans>

<beans profile="cloud">
    <cloud:data-source id="actmonDataSource" service-name="postgres-actmon-db-service" />
</beans>

<beans profile="default,cloud">
    <bean id="jpaVendorAdapter"
        class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="database" value="POSTGRESQL" />
    </bean>
</beans>

当我部署 https://gist.github.com/anonymous/3986a1a7cea4f20c096e 时来自 CF 的输出。请注意,它正在跳过 javax.sql.DataSources 的自动重新配置

【问题讨论】:

  • Spring 应用程序中绑定服务的自动重新配置仅在您将一个给定类型的服务绑定到您的应用程序时启用。见docs.cloudfoundry.org/buildpacks/java/…。在这种情况下,您正在手动配置数据源,因此不需要自动重新配置。如果您绑定了多个数据库,则自动重新配置无法知道应该将哪个绑定的数据库用于哪个目的。
  • 您确定“云”配置文件在您的应用被推送时被激活? Java buildpack 的某些版本并非在所有情况下都自动激活此配置文件。尝试运行cf set-env appname SPRING_PROFILES_ACTIVE cloud 以确保。
  • 谢谢。文档使它更清晰一些。我原以为自动重新配置和 spring-cloud-connectors 是捆绑在一起的。手动配置意味着 spring-cloud。因此,对于多个数据源,文档中的建议说使用 @Qualifier 注释来区分。日志确实表明正在激活云配置文件。
  • 认为我已经确定了 Scott 的问题。我们正在使用PropertySourcesPlaceholderConfigurer 并通过配置为指向cloud:data-source cic.properties.dataSource 的DAO 将属性加载到其中。 PropertySourcesPlaceholderConfigurerPriorityOrdered 实现 bean 工厂后处理器。这里的问题似乎是创建服务 bean 的 CloudServiceIntroducer 类只是一个常规的 bean 工厂后处理器,因此在加载属性源时不存在。有没有办法解决这个问题,也许实现PriorityOrderedtks

标签: spring-cloud spring-cloud-connectors


【解决方案1】:

首先,Thomas 的帖子已经很老了,并且引用了一个已弃用的支持库。您应该使用 Spring Cloud Connectors dependencies 而不是 org.cloudfoundry:cloudfoundry-runtime:0.8.1 依赖项。

然后您可以按照instructions provided 将 XML 配置与 Spring Cloud 连接器一起使用。对于相同类型的多个服务,您需要为每个 bean 指定服务的名称。按照您的示例,假设您创建了两个名为 inventory-dbcustomer-db 的 CF 数据库服务,可能看起来像这样:

<bean id="entityManagerFactory"
   class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="inventory-dataSource" />
    <property name="persistenceUnitName" value="activity-monitor" />
    <property name="jpaVendorAdapter" ref="jpaVendorAdapter"/>
    <property name="jpaProperties">
        <value>
            hibernate.format_sql=true
        </value>
    </property>
</bean>

<beans profile="cloud">
    <cloud:data-source id="inventory-dataSource" service-name="inventory-db">
    <cloud:data-source id="customer-dataSource" service-name="customer-db">
</beans>

【讨论】:

  • 嗨,斯科特。用附加信息编辑了我的问题。抱歉,对那篇文章的引用是我发现的。我实际上并没有使用这些库。我正在使用 Spring Cloud 连接器的最新 GA 版本。
  • 没问题,我不确定您是否使用的是较旧的库,只是想确定一下。
【解决方案2】:

我已经设法通过使用 spring cloud:data-source, CloudDataSourceFactory 使用的工厂 bean 解决了这个问题。创建此实例并连接配置,包括 CF 服务的service-name。这避免了我们的 PropertySourcesPlaceholderConfigurer 在定义 bean 之前尝试使用数据源的问题。

    <!--
        configure cloud data source for using CloudDataSourceFactory; this is what spring cloud:data-source is using;
        required to manually wire this data source bean as cloud:data-source bean gets defined in a phase after our
        PropertySourcesPlaceholderConfigurer bean.
    -->
    <bean id="cic.properties.dataSource" class="org.springframework.cloud.service.relational.CloudDataSourceFactory">
        <constructor-arg value="oracle-cicadm-db-service" />
        <constructor-arg>
            <!-- configuring minimal data source as it is used only to bootstrap properties on app start-up -->
            <bean class="org.springframework.cloud.service.relational.DataSourceConfig">
                <constructor-arg>
                    <bean class="org.springframework.cloud.service.PooledServiceConnectorConfig.PoolConfig">
                        <constructor-arg value="0" />
                        <constructor-arg value="2" />
                        <constructor-arg value="180" />
                    </bean>
                </constructor-arg>
                <!-- ConnectionConfig not required for cic.properties.dataSource so setting to null -->
                <constructor-arg value="#{ null }" />
            </bean>
        </constructor-arg>
    </bean>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-29
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 2011-03-05
    • 2021-01-03
    相关资源
    最近更新 更多