BeanCreationException: No unique bean of type

本文介绍了在Spring框架中,当存在多个相同类型的Bean时如何解决依赖注入冲突的问题。提供了两种解决方案:一是使用@Qualifier注解明确指定所需的Bean;二是利用@Resource注解按名称或类型进行精确匹配。

我定义了一个基类接口BaseDao下面有些update\save的方法; 

然后我用一个BaseDaoImpl去实现这个接口;好啦然后我现在有两个Dao接口,一个ADao extends BaseDao,一个BDao extends BaseDao; 然后再有这两个Dao的实现: ADaoImpl extends  BaseDaoImpl implements ADao; BDaoImpl extends BaseDaoImpl  implements BDao; 

这两个实现都加了@repository。结果就是启动错: 

No unique bean of type [com.a.b.BaseDao] is defined: expected single matching bean but found 2: [aDaoImpl, bDaoImpl] 


出现这个异常的原因是因为我用了@Autowird这个注解这个注解是根据类型的方式搜索匹配的找到了两个相符的依赖类对于上述配置就是找到了basedao 的两个 bean: adaoimpl , bdaoimpl。 


对于这种同类型class有多个实例的解决方案的一种方案是继续延用autowired不过通过@Qualifier指明是哪个名字的bean,如: 

Java代码  
  1. @Autowired  
  2.  public void setADao(@Qualifier("aDaoImpl") ADao adao) {  
  3.   this.adao= adao;  
  4.  }  


另外一种方案是使用@Resource这个注解其功能与@autowired差不多但是可以通过指定bean name或bean type注入相关bean,默认是按name注入比autowired灵活很多如: 
Java代码  
  1. @Resource  
  2. private ADao aDaoImpl;  
这是一个 Spring 框架中常见的依赖注入异常,具体错误是: ``` NoUniqueBeanDefinitionException: No qualifying bean of type 'com.csii.log.config.LogProperties' available: expected single matching bean but found 2 ``` ### 异常原因分析: Spring 容器在尝试自动装配(autowire)`LogProperties` 类型的 Bean 时,发现容器中存在 **两个相同类型的 Bean**,分别是: - `logProperties` - `log.enabled-com.csii.log.config.LogProperties` 这导致 Spring 不知道应该注入哪一个,从而抛出 `NoUniqueBeanDefinitionException`。 这种情况通常发生在以下几种场景中: 1. **使用了 @ConfigurationProperties 注解并指定了多个前缀配置项**: ```java @Component @ConfigurationProperties(prefix = "log") public class LogProperties { ... } ``` 如果你在配置文件中有类似如下内容: ```yaml log: enabled: true other-prop: value ``` Spring 可能会将 `log.enabled` 作为一个单独的 Bean 创建出来(如果某些库做了特殊处理或自定义配置类加载机制)。 2. **手动定义了一个名为 `logProperties` 的 Bean**,同时又通过 `@ConfigurationProperties` 自动生成了一个同类型 Bean。 3. **多个模块/依赖引入了相同的 Bean 定义**,或者有重复的 `@Bean` 或 `@Component` 注解。 --- ### 解决方法: #### ✅ 方法一:使用 `@Primary` 标注首选 Bean 如果你确定只需要其中一个 Bean 被使用,可以在其中一个 Bean 上加上 `@Primary` 注解: ```java @Component @ConfigurationProperties(prefix = "log") @Primary // 设置为首选 Bean public class LogProperties { // ... } ``` 这样 Spring 就会优先使用这个 Bean。 --- #### ✅ 方法二:使用 `@Qualifier` 明确指定要注入的 Bean 名称 在注入的地方明确指定 Bean 名称: ```java @Resource(name = "logProperties") // 或者使用 @Autowired + @Qualifier private LogProperties logProperties; ``` 如果是构造函数注入: ```java @Autowired public WebTraceFilter(@Qualifier("logProperties") LogProperties logProperties) { this.logProperties = logProperties; } ``` --- #### ✅ 方法三:检查是否重复定义了 Bean 查看你的项目中是否有其他地方重复定义了 `LogProperties` Bean,例如: ```java @Bean public LogProperties logProperties() { return new LogProperties(); } ``` 如果有,请移除或合并这些 Bean 定义。 --- #### ✅ 方法四:避免生成额外的 Bean(检查依赖库) 有些第三方库可能会根据配置自动生成 Bean,比如你看到的 `log.enabled-com.csii.log.config.LogProperties`,可能是某个日志组件读取配置后动态创建的。你可以: - 升级相关依赖版本,修复潜在的 Bug。 - 使用 `@ConditionalOnMissingBean` 避免冲突。 --- ### 示例代码: ```java @Component @ConfigurationProperties(prefix = "log") @Primary public class LogProperties { private boolean enabled; private String logPath; // Getters and setters } ``` 注入使用示例: ```java @RestController public class MyController { @Resource(name = "logProperties") private LogProperties logProperties; // ... } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值