spring-集成:SplitterFactoryBean 只能被引用一次

spring-integration: SplitterFactoryBean may only be referenced once

我有一个 Spring 项目( 不是 使用 Spring 启动,如果相关的话)我正在尝试连接到本地数据库使用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 集成有何关系。但是,我根本不知道我正在尝试 'reuse' 任何事情。引用的问题似乎也与数据库配置无关。

我的 setup/configuration 有点复杂,所以我会尝试引用看起来相关的部分。

我有一个 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,为了完整性而包括在内。内部 class 配置在那里,因为还有一个单独的嵌入式数据库单元测试配置 - 那个工作正常!)

现在我的顶层工程中使用了上面的工程,包含了实际的应用。它是那里的 Maven 运行时依赖项。我在这个项目的 XML 配置中导入配置 class,使用 this method:

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

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

我知道问题出在哪里,但我仍然不知道它与 <splitter>.

有什么关系

问题是 Config class 除了数据库之外,还包含一个用于加密数据的 bean。原来这个bean也是在顶层项目使用的另一个库中定义的。解决这个重复的 bean 问题使错误消失了。

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

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