Spring @Primary作用和实现原理详解

 更新时间:2023年07月25日 11:53:56   作者:刘牌  
今天分享一下Spring中的@Primary注解,Primary的意思是主要的,我们在使用spring的时候,难免会定义多个类型相同的bean,这时候如果不采取一些方法,那么是无法正常使用bean的,所以本就给大家介绍Spring @Primary的作用和实现原理

根据类型或者名称获取bean

根据名称获取bean这是很好理解的,在spring中,定义bean的方式有很多,不同通常都是@Component注解和@Bean注解来注册bean,使用@Component的时候我们可以指定名称,如果不指定,则就为类名的名称,只不过首字母小写,使用@Bean的时候,也可以指定,不指定的话则为方法名称,但是根据类型获取,之前不是很理解,其实类型就是接口,我们知道接口一般是不做任何实现的,由实现类来进行具体逻辑实现,可以有多个实现类,比如UserService接口有UserServiceImpl1和UserServiceImpl2两个实现类,那么我们就可以说UserServiceImpl1和UserServiceImpl2的类型是UserService,在spring中,这两个实现类如果定义成bean,那么都会被注册进spring IOC容器中,但是在获取的时候是有问题的。

byName

如果根据名称获取,那么是没问题的,因为注册进IOC容器时是注册了两个不同名称的bean,所以根据名称获取,只获取到了一个bean,所以能获取成功。

byType

如果根据类型获取,因为注册了两个bean,但是它们的类型是相同的,这时候直接根据类型获取,那么就会获取到两个bean,spring不能返回那个,所以就抛出异常。

No qualifying bean of type 'io.steakliu.spring.ioc.annotation.primary.PrimaryService' available: expected single matching bean but found 2: primaryServiceImpl1,primaryServiceImpl2

解决方案

存在多个类型的bean时,可以通过@Qualifier注解指定名称,我们也可以在注入bean的时候指定具体的bean名称,不过这样的话就会变得很变扭,所以使用@Qualifier还是比较合理和规范,当然,也可以使用@Primary来,但实际上@Primary能解决的问题我觉得只是给了一个默认值,这样在获取bean的时候不会报错,当需要注入同一类型下的其他bean时,依旧需要指定名称。

实现原理

如果我们使用@Component或@Bean注解注册bean的时候,spring启动后会扫描工程路径下的包,然后找出相应的类,并解析相应的Bean,如果带有@Primary注解,那么就会将BeanDefinition的primary属性设置为true,然后将BeanDefinition注册到BeanFactory,如下所示。

在获取bean的时候,首先会获取类型下面的所有bean,然后再根据bean的名字去获取BeanDefination,最后选择primary属性为true的bean返回,如果同一类型下的bean都加了@Primary注解,那么获取的时候会报错。

以上就简单的分析了@Primary的源码,其实是比较简单的,primary作为bean定义信息中的一个属性,spring扫描到了标有这个注解,就会将BeanDefinition的primary设置为true,获取获取bean的时候,就再次取出Beandefinition,判断primary属性,然后从获取的候选bean中选出primary为true的那个。

到此这篇关于Spring @Primary注解作用和实现原理详解的文章就介绍到这了,更多相关Spring @Primary作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java 获取路径的各种方法(总结)

    java 获取路径的各种方法(总结)

    下面小编就为大家带来一篇java 获取路径的各种方法(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-08-08
  • Spring boot如何开启跨域配置

    Spring boot如何开启跨域配置

    这篇文章主要介绍了Spring boot如何开启跨域配置问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 使用SpringBoot整合高德地图实现路线规划功能

    使用SpringBoot整合高德地图实现路线规划功能

    在日常的开发项目中,地图服务是很多系统的核心能力之一,尤其是在物流、同城配送、出行导航等领域,在近期的一个项目中,需要实现用户下单后,系统需要根据起点和终点地址,自动计算推荐路径,所以本文给大家分享了如何使用SpringBoot整合高德地图实现路线规划功能
    2025-07-07
  • 使用JPA插入枚举类型字段

    使用JPA插入枚举类型字段

    这篇文章主要介绍了使用JPA插入枚举类型字段,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • Java二分算法题目练习实战教程

    Java二分算法题目练习实战教程

    二分查找(Binary Search)是一种非常高效的查找算法,它在有序数组或有序列表中通过反复将搜索范围分为两半来查找目标元素,这篇文章主要介绍了Java二分算法题目练习的相关资料,需要的朋友可以参考下
    2025-11-11
  • Spring ProtocolResolver策略接口示例

    Spring ProtocolResolver策略接口示例

    这篇文章主要介绍了Spring ProtocolResolver策略接口示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java CRM系统用户登录功能实现代码实例

    Java CRM系统用户登录功能实现代码实例

    这篇文章主要介绍了Java CRM系统用户登录功能实现代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java从入门到起飞之变量与运算符详解

    Java从入门到起飞之变量与运算符详解

    这篇文章主要介绍了Java编程语言中的关键字、标识符、变量、基本数据类型以及运算符等基本概念和用法,它涵盖了变量声明、赋值、类型转换、字符串操作以及运算符优先级等内容,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2025-03-03
  • Java后端本地调试实用方法总结大全

    Java后端本地调试实用方法总结大全

    这篇文章主要介绍了Java后端本地调试实用方法总结大全的相关资料,每个部分都提供了实用的技巧和工具推荐,帮助开发者提高调试效率,文中介绍的非常详细,需要的朋友可以参考下
    2026-01-01
  • SpringBoot将多个文件夹进行压缩的两种方法(浏览器下载和另存为)

    SpringBoot将多个文件夹进行压缩的两种方法(浏览器下载和另存为)

    Spring Boot项目通常不会自动对文件夹进行压缩,不过,在打包应用时,如果你使用了Maven或Gradle这样的构建工具,并且配置了相应的插件,可以在打成jar或war包的时候将依赖的库文件合并并压缩,本文介绍了SpringBoot将多个文件夹进行压缩的两种方法
    2024-07-07

最新评论