当前位置: 首页 > article >正文

Spring中@Primary注解的作用与使用

在 Spring 框架中,@Primary 注解用于解决依赖注入时的歧义性(Ambiguity)问题。当 Spring 容器中存在多个相同类型的 Bean 时,通过 @Primary 标记其中一个 Bean 作为默认的首选注入对象


核心作用:

  1. 解决多个同类型 Bean 的冲突
    当有多个实现同一接口或相同类型的 Bean 时,Spring 无法自动确定注入哪个 Bean,会抛出 NoUniqueBeanDefinitionException。使用 @Primary 可指定默认注入的 Bean。

  2. 隐式选择优先级
    被标记为 @Primary 的 Bean 会被优先注入,无需额外使用 @Qualifier 指定名称。


使用示例:

场景定义

假设有一个支付接口 PaymentService 和两个实现类:

public interface PaymentService {void pay();
}@Component
public class CreditCardService implements PaymentService {@Overridepublic void pay() { System.out.println("信用卡支付"); }
}@Component
public class AlipayService implements PaymentService {@Overridepublic void pay() { System.out.println("支付宝支付"); }
}
问题:依赖注入歧义

若直接注入 PaymentService,Spring 会报错:

@Autowired
private PaymentService paymentService; // 抛出 NoUniqueBeanDefinitionException
解决方案:使用 @Primary

标记其中一个实现类为默认首选:

@Component
@Primary // 指定为默认注入的 Bean
public class AlipayService implements PaymentService { ... }

此时注入会成功选择 AlipayService

@Autowired
private PaymentService paymentService; // 隐式注入 AlipayService

与其他注解的优先级:

  1. @Primary vs @Qualifier

    • @Qualifier 显式指定 Bean 名称的优先级高于 @Primary
    • 例如:@Autowired @Qualifier("creditCardService") 会覆盖 @Primary
  2. 多个 @Primary 的冲突
    如果多个同类型 Bean 都被标记为 @Primary,Spring 会再次抛出歧义异常。


常见使用场景:

  1. 数据库多数据源配置
    在多个 DataSource Bean 中,标记默认使用的数据源。
  2. 不同环境下的实现类
    例如在测试和生产环境中提供同一接口的不同实现,通过 @Primary 切换默认实现。
  3. 第三方库的扩展
    当覆盖第三方库提供的 Bean 时,将自己的实现标记为 @Primary

配置方式:

除了注解在类上,也可以在 @Bean 方法中使用:

@Configuration
public class AppConfig {@Bean@Primary // 标记此 Bean 为首选public PaymentService alipayService() {return new AlipayService();}
}

总结:

场景解决方案
多个同类型 Bean,需默认注入一个在目标 Bean 添加 @Primary
需要临时覆盖默认注入配合 @Qualifier 指定名称

关键点@Primary 是 Spring 解决依赖注入歧义性的轻量级方案,通过隐式指定默认 Bean 简化配置,但在需要精确控制的场景中仍需结合 @Qualifier 使用。

http://www.lryc.cn/news/2401450.html

相关文章:

  • Spring Boot + Elasticsearch + HBase 构建海量数据搜索系统
  • [zynq] Zynq Linux 环境下 AXI BRAM 控制器驱动方法详解(代码示例)
  • 【大模型:知识图谱】--5.neo4j数据库管理(cypher语法2)
  • 六、数据库的安全性
  • 贪心算法应用:装箱问题(BFD算法)详解
  • C#学习第27天:时间和日期的处理
  • 编程技能:格式化打印05,格式控制符
  • MPLAB X IDE ​软件安装与卸载
  • windows编程实现文件拷贝
  • [6-01-01].第12节:字节码文件内容 - 属性表集合
  • 基于机器学习的水量智能调度研究
  • 深度解码:我如何用“结构进化型交互学习方法”与AI共舞,从学习小白到构建复杂认知体系
  • 深入浅出 Scrapy:打造高效、强大的 Python 网络爬虫
  • ES6 Promise 状态机
  • Axure 与 Cursor 集成实现方案
  • 汽车加气站操作工证考试重点
  • 贪心算法应用:带权任务间隔调度问题详解
  • 用电脑控制keysight示波器
  • LLaMA-Factory - 批量推理(inference)的脚本
  • React从基础入门到高级实战:React 高级主题 - 测试进阶:从单元测试到端到端测试的全面指南
  • Ansible 剧本精粹 - 编写你的第一个 Playbook
  • 【Elasticsearch】Elasticsearch 核心技术(二):映射
  • 【计算机网络】网络层协议
  • .NET Core接口IServiceProvider
  • 结构型设计模式之Proxy(代理)
  • 案例分享--汽车制动卡钳DIC测量
  • Redis Set集合命令、内部编码及应用场景(详细)
  • C++算法动态规划1
  • 【快速预览经典深度学习模型:CNN、RNN、LSTM、Transformer、ViT全解析!】
  • KaiwuDB在边缘计算领域的应用与优势