Spring 容器中存在两个相同类型的 Bean 解决方案

210 阅读2分钟

背景

Field sysUserRoleEOService in com.one.user.service.UserSupplierEOService 
required a single bean, but 2 were found: - oneSysRoleServiceImpl: defined in file 
[/Users/snackpub/Desktop/mywork/project1/one-next/one-modules/one-module-
login/target/classes/com/one/login/impl/OneSysRoleServiceImpl.class] - 
oneSysRoleService: defined in file [/Users/snackpub/Desktop/mywork/project1/one-
next/one-modules/one-module-
sys/target/classes/com/one/sys/impl/OneSysRoleService.class]

这个错误表明 Spring 容器中存在两个 OneSysRoleService 类型的 Bean,导致依赖注入时无法确定使用哪一个。以下是解决方案:

1. 使用 @Primary 注解

  • 在其中一个实现类上添加 @Primary 注解,使其成为默认 Bean。
    @Service
    @Primary
    public class OneSysRoleServiceImpl implements OneSysRoleService {
        // 实现代码
    }
    

2. 使用 @Qualifier 注解

  • 在注入时指定具体的 Bean 名称。
    @Autowired
    @Qualifier("oneSysRoleServiceImpl")
    private OneSysRoleService oneSysRoleService;
    

3. 重命名 Bean

  • 确保每个 Bean 的名称唯一。
    @Service("oneSysRoleServiceImpl")
    public class OneSysRoleServiceImpl implements OneSysRoleService {
        // 实现代码
    }
    
    @Service("oneSysRoleService")
    public class OneSysRoleService implements OneSysRoleService {
        // 实现代码
    }
    

4. 检查 Bean 扫描路径

  • 确保没有重复扫描相同的类。
    @ComponentScan(basePackages = {"com.lcw.one.login", "com.lcw.one.sys"})
    public class AppConfig {
        // 配置代码
    }
    

5. 合并实现类

  • 如果两个实现类功能相似,考虑合并为一个。

总结

通过 @Primary@Qualifier、重命名 Bean 或调整扫描路径,可以解决 Bean 冲突问题。选择最适合你项目的方式。


另外一种情况: 如果全局搜索(如 IDE 的 Ctrl + Shift + F 或 Cmd + Shift + F)只找到一个 WebLogAspect 类(例如 com.lcw.one.main.aop.WebLogAspect),但 Spring 仍然报错说存在冲突的 webLogAspect Bean,可能是以下原因:

可能的原因和解决方案

1. 重复的类文件(编译后存在多个版本)

  • 问题
    虽然源代码中只有一个类,但编译后的 target/classes 或打包的 JAR 中可能包含多个版本的 WebLogAspect.class(例如来自不同模块或依赖)。
  • 检查方法
    在项目目录下运行: find . -name "WebLogAspect.class"

image.png

  • 解决
    如果发现重复的类文件,需排除冲突的依赖或合并模块。