首页 > 解决方案 > spring-integration:SplitterFactoryBean 只能被引用一次

问题描述

我有一个 Spring 项目(如果相关,使用 Spring Boot),我正在尝试使用 Postgres JDBC 驱动程序连接到本地数据库。(本地数据库实际上是 Yugabyte,但应该与 Postgres 驱动程序完全兼容。)

启动应用程序时,我收到以下错误消息:

java.lang.IllegalArgumentException: An AbstractMessageProducingMessageHandler may only be referenced once (org.springframework.integration.config.SplitterFactoryBean#0) - use scope="prototype"
    at org.springframework.util.Assert.isTrue(Assert.java:118)
    at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.checkReuse(AbstractStandardMessageHandlerFactoryBean.java:168)
    at org.springframework.integration.config.AbstractStandardMessageHandlerFactoryBean.createHandler(AbstractStandardMessageHandlerFactoryBean.java:137)
    at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.createHandlerInternal(AbstractSimpleMessageHandlerFactoryBean.java:186)
    at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:174)
    at org.springframework.integration.config.AbstractSimpleMessageHandlerFactoryBean.getObject(AbstractSimpleMessageHandlerFactoryBean.java:59)
    at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:171)
    ... 52 more

我根本无法放置此错误。Stack Overflow 上有一个类似的问题,但提问者似乎知道他们在做什么,以及这与 Spring 集成有何关系。但是,我根本不知道我正在尝试“重用”任何东西。引用的问题似乎也与数据库配置无关。

我的设置/配置有点涉及,所以我会尝试引用看起来相关的部分。

我有一个 dao 层项目,它具有以下 gradle 依赖项(等等):

implementation("org.springframework:spring-context:5.2.2.RELEASE")
implementation("org.springframework:spring-jdbc:5.2.2.RELEASE")
implementation("org.jooq:jooq-kotlin:3.14.11")
runtimeOnly("org.postgresql:postgresql:42.2.19.jre7")

在同一个项目中,我有一些配置(在 Kotlin 中):

@Configuration
open class Config {
    @Bean
    open fun jdbcTemplate(dataSource: DataSource): JdbcTemplate = JdbcTemplate(dataSource)

    @Bean
    open fun dslContext(): DSLContext = DefaultDSLContext(SQLDialect.POSTGRES)

    @Configuration
    @Profile("!unittest")
    open inner class NonTestConfig {
        @Bean
        open fun dataSource(): DataSource {
            return DriverManagerDataSource().apply {
                // Hardcoded properties to be replaced by values from property file
                setDriverClassName("org.postgresql.Driver")
                url = "jdbc:postgresql://localhost:5433/demo"
                username = "yugabyte"
                password = "yugabyte"
            }
        }
    }
}

(注意: DSLContext bean 用于 JOOQL,为了完整性而包含在内。内部类配置在那里是因为嵌入式数据库还有一个单独的单元测试配置 - 一个工作正常!)

现在,上面的项目在我的包含实际应用程序的顶级项目中使用。这是一个 Maven 运行时依赖项。我使用这种方法在这个项目的 XML 配置中导入了配置类:

<context:annotation-config />
<bean class="my.package.Config" />

然后尝试启动应用程序会产生错误消息。

标签: springpostgresqljdbcspring-integration

解决方案


我弄清楚了问题所在,但我仍然不知道它与<splitter>.

问题是 Config 类,除了数据库的东西,还包括一个 bean 来加密数据。原来,这个bean也是在顶层项目使用的另一个库中定义的。修复此重复 bean 问题使错误消失。

我以一种迂回的方式发现了这一点:我将 dao 项目及其配置包含在另一个使用 Spring Boot 的顶级项目中。这导致了关于加密器 bean 有两个定义的明确错误消息。

如果有人可以解释为什么错误消息在非引导情况下如此神秘,那将是一个很好的补充答案。


推荐阅读