Xml 在具有 Spring Data JPA 的 Spring 引导项目中为 JdbcChannelMessageStore 配置

Xml configuration for JdbcChannelMessageStore in a Spring Boot project with Spring Data JPA

我是 Spring 集成的新手,想使用由 JdbcChannelMessageStore 支持的队列通道。 由于我们的项目使用 Spring Boot with Spring Data JPA,我希望有一个 integration-context.xml 配置,其中现有的数据库连接被重用。但是我很难让它发挥作用。

不幸的是,我找不到任何使用 JdbcChannelMessageStore 的示例项目。谁能为此提供一些很好的示例实现?

非常感谢。

P.S.: 这是我最后的 integration-context.xml 版本:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:int="http://www.springframework.org/schema/integration"
       xsi:schemaLocation="http://www.springframework.org/schema/integration https://www.springframework.org/schema/integration/spring-integration.xsd
        http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">

  <int:channel id="outgoingChannel">
    <int:queue message-store="outgoingMessageChannelStore"/>
  </int:channel>

  <bean id="dp"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="${spring.datasource.password}" />
    <property name="username" value="${spring.datasource.username}" />
    <property name="password" value="${spring.datasource.password}" />
  </bean>


  <bean id="outgoingMessageChannelStore" class="org.springframework.integration.jdbc.store.JdbcChannelMessageStore">
    <property name="dataSource" ref="dp"/>
    <property name="channelMessageStoreQueryProvider" ref="jdbcChannelMessageStoreQueryProvider"/>
    <property name="region" value="TX_TIMEOUT"/>
    <property name="usingIdCache" value="true"/>
  </bean>

  <bean id="jdbcChannelMessageStoreQueryProvider" class="org.springframework.integration.jdbc.store.channel.OracleChannelMessageStoreQueryProvider" />


  <int:transaction-synchronization-factory id="jdbcChannelMessageStoreFactory">
    <int:after-commit expression="@jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" />
    <int:after-rollback expression="@jdbcChannelMessageStore.removeFromIdCache(headers.id.toString())" />
  </int:transaction-synchronization-factory>
</beans>

有了这个,我在启动时遇到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.service.spi.ServiceException: Unable to create requested service [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

...

Caused by: org.hibernate.HibernateException: Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set

好吧,既然你说你也使用 Spring Boot,你可能错过了它 auto-configure 对我们来说是一个 DataSource bean 的事实。在你的配置中拥有 dp bean 它只是忽略了 auto-configuration 并尝试将它应用到你需要的任何地方 DataSource,就像 Hibernate auto-configuration.

您真正需要的恰恰相反 - 您需要为此 Spring 集成配置重用 auto-configured DataSource。当然,如果您的 JdbcChannelMessageStore 将依赖与提到的 Spring Data JPA 相同的数据库。

所以,您需要的只是删除 dp bean 定义,并在 outgoingMessageChannelStore bean 定义中为 <property name="dataSource" 使用 dataSource 名称。

一些备注:

  1. 我们不需要 usingIdCache Oracle,因此不需要 jdbcChannelMessageStoreFactory 来处理缓存。 JavaDocs:
     * <p>If using the provided
     * {@link org.springframework.integration.jdbc.store.channel.OracleChannelMessageStoreQueryProvider},
     * don't set {@link #usingIdCache}
     * to true, as the Oracle query will ignore locked rows.</p>
  1. 尝试配置 Spring 与 Java 集成和注释配置(甚至 Java DSL)。这样你就不会被一个 bean 名称所束缚(比如 dataSource),只会有一个用于普通 DataSource 类型的 bean 方法参数注入,而 Spring 容器将为你注入一个auto-configured 豆。