Spring非Boot项目启动报SplitterFactoryBean仅可引用一次错误求解
问题根因
报错本质与数据库配置无直接关联,是Spring Integration组件被重复实例化触发的校验规则,核心触发点有两个:
- 你显式列出的依赖中未引入Spring Integration,但顶层业务项目的其他依赖通过传递依赖引入了Spring Integration相关组件包
- 配置加载逻辑重叠:你在XML中同时开启了
<context:annotation-config />,又将带@Configuration注解的Config类显式声明为普通Bean,导致配置类被重复加载,内部Bean定义被重复注册,刚好触发了Spring Integration对单例消息处理组件的复用校验。
解决方案
按优先级依次执行:
1. 修正配置类加载方式
不要在XML中将@Configuration注解的配置类直接声明为Bean,改用组件扫描加载:
<!-- 替换原有的<bean class="my.package.Config" />配置 --> <context:component-scan base-package="my.package" /> <context:annotation-config />
如果不需要扫描整个包,也可以单独通过@Import注解导入配置类,避免重复加载。
2. 排查并排除不必要的Spring Integration依赖
修改配置后如果仍然报错,排查依赖树找到传递引入Spring Integration的上游依赖,不需要使用Spring Integration功能的话直接排除:
- Gradle排查命令:
./gradlew dependencies - Maven排查命令:
mvn dependency:tree
Maven排除示例:
<dependency> <groupId>传递引入Spring Integration的依赖组ID</groupId> <artifactId>依赖 artifact ID</artifactId> <version>版本号</version> <exclusions> <exclusion> <groupId>org.springframework.integration</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
3. 显式设置组件作用域(兜底方案)
如果业务确实需要使用Spring Integration功能,给对应的Splitter组件显式设置prototype作用域即可,添加如下配置:
@Bean public BeanFactoryPostProcessor springIntegrationSplitterScopeFix() { return beanFactory -> { BeanDefinition splitterDefinition = beanFactory.getBeanDefinition("org.springframework.integration.config.SplitterFactoryBean#0"); splitterDefinition.setScope("prototype"); }; }
额外优化提示:你当前定义的
dslContextBean未绑定数据源,后续使用JOOQ执行查询会报错,建议调整为:@Bean open fun dslContext(dataSource: DataSource): DSLContext = DefaultDSLContext(dataSource, SQLDialect.POSTGRES)
内容的提问来源于stack exchange,提问作者Merlin's Beard
相关产品推荐
相关产品推荐

