spring - 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" />
然后尝试启动应用程序会产生错误消息。
解决方案
我弄清楚了问题所在,但我仍然不知道它与<splitter>
.
问题是 Config 类,除了数据库的东西,还包括一个 bean 来加密数据。原来,这个bean也是在顶层项目使用的另一个库中定义的。修复此重复 bean 问题使错误消失。
我以一种迂回的方式发现了这一点:我将 dao 项目及其配置包含在另一个使用 Spring Boot 的顶级项目中。这导致了关于加密器 bean 有两个定义的明确错误消息。
如果有人可以解释为什么错误消息在非引导情况下如此神秘,那将是一个很好的补充答案。
推荐阅读
- kotlin - Mono.fromCallable 中的异常不会导致错误
- c - 取消引用对指向数组的指针有何作用?
- javascript - 按钮动画错误:无法读取未定义的属性“requestAnimationFrame”(第 11 行)
- java - 为什么 s:mvcUrl 函数在不同的视图上返回不同的结果?
- javascript - 有人可以在以下示例中解释 ...spread 运算符的使用吗?
- r - 估计 R 中的向量中有多少个连续的真实元素
- c# - 将包含布尔、ushort、hex、int、float 的字符串解析为 ushort 的优雅方法?
- excel - 将2个excel文件中的数据合并到一个主文件中
- php - 将数组循环分成两部分
- html - 如何在加载时获取角度 6 中下拉列表的选定值(不是 onchange)