NoUniqueBeanDefinitionException 尽管只有一个实现抛出

NoUniqueBeanDefinitionException thrown though there is only one implementation

我有一个 MyService class 应该注入 repository 字段。

public class MyService {
    @Autowired
    private MyRepository repository;
// ...ommited
}

并且有 MyRepository 接口仅由 MyRepositoryImpl class 和 MyBatis@Mapper annotation 实现。

public interface MyRepository {
// ...ommited
}

@Mapper
public interface MyRepositoryImpl extends MyRepository {
// ...ommited
}

当我尝试启动 SpringBootApplication 时,抛出 NoUniqueBeanDefinitionException

@SpringBootApplication(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
@MapperScan(nameGenerator = FullyQualifiedAnnotationBeanNameGenerator.class)
public class App {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }
}
(...omitted)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'com.example.MyService':
Unsatisfied dependency expressed through field 'repository'; 
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type 'com.example.MyRepository' available: 
expected single matching bean but found 2: com.example.MyRepositoryImpl,com.example.MyRepository
(...omitted)

为什么 MyRepository 接口注册为 bean 之一,即使它没有 @Component 注释也不包含任何 bean 配置?

而且我发现如果我不将 FullyQualifiedAnnotationBeanNameGenerator 用作 nameGenerator,一切正常。

有什么想法吗?

可以有许多其他方法将接口标记为 bean。其中一些是:

  1. @RepositoryDe​​finition 上面的 MyRepository 接口
  2. MyRepository 扩展了 CrudRepository 或 JpaRepository
检查这些是否存在。

更新一:-
问题似乎在 @MapperScan。它所做的是扫描包中的所有接口并将它们注册为 bean;如果我没记错的话 MyRepositoryMyRepositoryImpl 在同一个包中。这就是为什么使用名称 com.example.MyRepositoryImplcom.example.MyRepository 创建 2 个 bean 的原因,并且基本上两者的类型与 MyRepositoryImpl extends MyRepository 相同。
现在,当您在 MyServicerepository 字段上使用 @Autowired 时,它会混淆要注入哪一个。要解决此问题,最简单的方法是使用 @Primary 而不是 MyRepositoy,这将在注入时优先考虑该接口。另一种方法是在接口和 MyServicerepository 字段上方使用 @Qualifier("uniqueName") 以及 @Autowired 指定要注入的接口。您可以访问 here 的官方文档以了解更多信息。
希望这对您有所帮助。

Spring 无法找出 class 应该实现 Repository 接口的 bean。
将注解@Repository 放在RepositoryImpl Class 之上。它会找到的。