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。其中一些是:
- @RepositoryDefinition 上面的 MyRepository 接口
- MyRepository 扩展了 CrudRepository 或 JpaRepository
检查这些是否存在。
更新一:-
问题似乎在 @MapperScan
。它所做的是扫描包中的所有接口并将它们注册为 bean;如果我没记错的话 MyRepository
和 MyRepositoryImpl
在同一个包中。这就是为什么使用名称 com.example.MyRepositoryImpl
、com.example.MyRepository
创建 2 个 bean 的原因,并且基本上两者的类型与 MyRepositoryImpl
extends MyRepository
相同。
现在,当您在 MyService
的 repository
字段上使用 @Autowired
时,它会混淆要注入哪一个。要解决此问题,最简单的方法是使用 @Primary
而不是 MyRepositoy
,这将在注入时优先考虑该接口。另一种方法是在接口和 MyService
的 repository
字段上方使用 @Qualifier("uniqueName")
以及 @Autowired
指定要注入的接口。您可以访问 here 的官方文档以了解更多信息。
希望这对您有所帮助。
Spring 无法找出 class 应该实现 Repository 接口的 bean。
将注解@Repository 放在RepositoryImpl Class 之上。它会找到的。
我有一个 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。其中一些是:
- @RepositoryDefinition 上面的 MyRepository 接口
- MyRepository 扩展了 CrudRepository 或 JpaRepository
更新一:-
问题似乎在 @MapperScan
。它所做的是扫描包中的所有接口并将它们注册为 bean;如果我没记错的话 MyRepository
和 MyRepositoryImpl
在同一个包中。这就是为什么使用名称 com.example.MyRepositoryImpl
、com.example.MyRepository
创建 2 个 bean 的原因,并且基本上两者的类型与 MyRepositoryImpl
extends MyRepository
相同。
现在,当您在 MyService
的 repository
字段上使用 @Autowired
时,它会混淆要注入哪一个。要解决此问题,最简单的方法是使用 @Primary
而不是 MyRepositoy
,这将在注入时优先考虑该接口。另一种方法是在接口和 MyService
的 repository
字段上方使用 @Qualifier("uniqueName")
以及 @Autowired
指定要注入的接口。您可以访问 here 的官方文档以了解更多信息。
希望这对您有所帮助。
Spring 无法找出 class 应该实现 Repository 接口的 bean。
将注解@Repository 放在RepositoryImpl Class 之上。它会找到的。