Spring依赖注入生成重复Bean触发NoUniqueBeanDefinitionException问题排查
Spring Bean重复实例化触发NoUniqueBeanDefinitionException的原因及解决方案
带#0后缀的全限定类名Bean是Spring的自动冲突兜底命名,说明项目中确实出现了同一类型Bean被重复注册的情况,常见原因如下:
- 父子上下文重复扫描:如果是传统Spring MVC项目,存在父上下文(Root WebApplicationContext)和子上下文(Servlet WebApplicationContext),两个上下文的扫描路径都包含了
FDDDefaultParameterResolver所在的包,就会分别实例化一次:父容器生成默认的简单类名BeanFDDDefaultParameterResolver,子容器重复扫描到后生成带#0后缀的全限定名Bean。 - 多扫描配置冲突:项目同时存在多种组件扫描配置,比如启动类/配置类的
@ComponentScan注解、XML配置的<context:component-scan>标签、第三方依赖包内的扫描配置,都覆盖了当前类所在包,导致多次扫描实例化。 - 手动注册Bean:代码中存在手动注册该类Bean的逻辑,比如通过
AnnotationConfigApplicationContext.register()、BeanDefinitionRegistry.registerBeanDefinition()等方法手动注册了一次,加上@Component注解扫描生成的实例,总共有两个同类型Bean。 - 类路径重复资源:编译目录下存在残留的旧class文件,或者引入的依赖Jar包中也存在同全限定名、同样加了
@Component注解的FDDDefaultParameterResolver类,被扫描器识别为两个不同的Bean实例。
快速排查方案
- 全局搜索项目所有配置中的扫描路径,确认是否存在对
osplus.dynssee.ie.ocp.bs.services.fdd包的重复扫描配置。父子上下文场景下建议路径隔离:父容器仅扫描Service、Dao等核心Bean,子容器仅扫描Controller相关Bean。 - 全局检索代码,检查是否存在手动注册
FDDDefaultParameterResolver类型Bean的逻辑,删除重复注册逻辑。 - 清空
target目录后重新编译,排查依赖Jar包是否存在同全限定名的重复类。 - 临时修复可以给
FDDDefaultParameterResolver添加@Primary注解,指定该Bean为优先注入的实例:
@Component @Primary public class FDDDefaultParameterResolver implements FDDParameterResolver { private FremdsystemProviderProvider fremdsystemProviderProvider; @Autowired public FDDDefaultParameterResolver(FremdsystemProviderProvider fPP) { this.fremdsystemProviderProvider = fPP; } // 原有方法不变 }
内容的提问来源于stack exchange,提问作者Schmutz
相关产品推荐
相关产品推荐

