介绍

今天共享一下Spring中的@Primary注解,Primary的意思是主要的,咱们在运用spring的时分,难免会界说多个类型相同的bean,这时分假如不采取一些办法,那么是无法正常运用bean的。

其实在刚开始运用spring的时分,一开始对于某些概念是很不清楚的,所以即使网上去找了许多答案,也是没有真实的了解,所以就导致许多东西都是似懂非懂,就比如依据类型和称号获取bean,一开始这个类型我是有点不太清楚的。

依据类型或许称号获取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,如下所示。

Spring @Primary作用和实现原理

在获取bean的时分,首先会获取类型下面的所有bean,然后再依据bean的名字去获取BeanDefination,最后选择primary特点为true的bean回来,假如同一类型下的bean都加了@Primary注解,那么获取的时分会报错。

Spring @Primary作用和实现原理

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

今天的共享就到这儿,感谢你的观看,下期见!