品牌型号:联想ThinkPad X1
系统:Windows10家庭版
软件版本:Spring 5.3.7
我们用Spring开发久了,都多多少少会遇到这样一个场景,一个接口,项目里写了不止一个实现类。这时候问题就来了,Spring到底会执行哪个实现?如果两个实现都需要用,又该怎么注入呢?这两个问题是连在一起的,如果搞不清楚前面的问题,那么第二个问题也就无从下手。应该有不少同学在这里踩过坑,出现过启动报错、注入了错误的实现、或者改了半天代码才发现根源在Bean的装配上。下面就给大家介绍一下Spring接口多个实现会执行哪个,Spring一个接口多个实现类怎么注入的相关内容。
一、Spring接口多个实现会执行哪个
这个问题没有一个固定的答案,因为Spring本身并不会自动决定执行哪个实现,执行哪个,完全取决于我们代码怎么写、配置怎么做。

如果一个接口只有一个实现类,Spring注入起来没有任何问题,直接装配那一个就行。一旦出现多个实现,Spring就懵了,因为它不知道我们想要哪个,如果什么都不配置,直接启动大概率会报NoUniqueBeanDefinitionException这个错误。这个报错的意思很直白,容器里找到了多个候选Bean,不知道该注入哪一个。

怎么告诉Spring呢?常见的方式有几种:可以用@Primary注解,标在某个实现类上,意思是"如果有歧义,优先用我";或者用@Qualifier,在注入的地方指定Bean的名称,精确告诉Spring要哪一个;还有一种就是Spring在找不到精确匹配的情况下,会尝试用字段名去匹配Bean的名称,但这种方式隐式依赖命名,不够直观,不推荐作为主要手段。

说到底Spring接口多个实现会执行哪个,是Bean装配的优先级问题。框架提供了机制,但具体怎么用,得结合业务场景来判断。
二、Spring一个接口多个实现类怎么注入
前面说的是Spring遇到多个实现会怎么处理,现在我们来看看更实际的问题,如果业务上就是需要多个实现,代码里该怎么写。
简单直接的方式就是用@Qualifier配合@Autowired使用,每个实现类注册到容器里都有自己的Bean名称,默认是类名首字母小写,注入的时候在@Qualifier里写上对应的名称,Spring就能精确找到我们要的那个。这种写法清晰,指向明确,多个实现并存的场景用起来很顺手。

另一种场景是需要把所有实现都拿到,动态决定用哪个,这时候我们可以用List或者Map来注入。注入List<接口类型>,Spring会把容器里这个接口的所有实现都塞进来,如果注入的是Map

还有一种情况值得单独提一下,用@Primary标注了主实现之后,普通的@Autowired注入会默认拿到这个主实现,其他地方如果需要非主实现,再配合@Qualifier指定,这种组合方式不用每个注入点都写@Qualifier,减少大量的重复标注代码。

以上就是Spring接口多个实现会执行哪个,Spring一个接口多个实现类怎么注入的全部内容了。一个接口多个实现,是Spring开发里很常见的场景,但也是容易踩坑的地方。Spring不会自作主张,出现多实现的情况下它会直接报错,解决办法要靠我们主动介入,用@Primary定主次,用@Qualifier精确指定,用List或Map全量获取。几种方式各有适用场景,灵活组合就能覆盖大部分业务需求。