Sprint Boot————@Qualifier、@Primary

引言

使用@Autowired自动注入时:

如果注入的接口有多个实现类,如下所示:

那么如果不指定具体是哪个实现类的Bean,在Spring Boot启动时就会发生异常(下图请点击查看):

 异常的描述信息非常简单,就是告诉开发者,自动注入的地方需要一个Bean,而spring 容器却找到了3个实现类的Bean。

Action(可以采取的行动): 考虑使用@Primary注解或@Qualifier注解。

 

@Primary

此注解用在类上面,官方解释如下:

简单翻译过来就是,这个注解相当于Spring 的xml配置文件中bean标签里的 primary属性。

它表示在需要自动注入一个单值依赖的地方,却有多个候选依赖,那么这个注解会指定一个类作为preference(偏好)选择。

可以简单理解为,我们把@Primary注解标记在任意一个类上面,在使用@Autowired注入的时候,如果不特殊指明(如何特殊指明请看@Qualifier的讲解),那么默认就注入被@Primary标记的类。

但是只可以指定一个类作为偏好类,否则依然会产生冲突。

@Qualifier

此注解用在属性上、方法上、参数上等,官方解释如下:

翻译过来就是说,这个注解用在属性上,或参数上,在自动注入的时候作为多个候选bean的限定。也可以使用在其他的随后会被用于限定bean的定制注解上。

其实大多数用于属性上和@Autowired一起联用。

这个注解有一个参数:

(default关键字应该是java8中引入的关键字,不过我也是第一次见过这种写法,可能是孤陋寡闻,各位大神轻喷)

稍微思考一下就可以猜到,如果不为@Qualifier注解指定参数那么默认使用类的默认别名,即类的首字母小写,比如:

ChineseTeacher类的默认别名是:chineseTeacher;

EnglishTeacher类的默认别名是:englishTeacher;

MathTeacher类的默认别名是:mathTeacher。

 使用默认别名的方法很简单,直接用类的默认别名来命名我们的自动注入对象,如下所示:

Teacher接口有三个实现类:ChineseTeacher、EnglishTeacher、MathTeacher,我们不需要使用@Primary,也不使用@Qualifier,直接在自动注入的变量上使用默认别名,依然可以注入成功。

是的,当我们在自动注入的时候使用类的默认别名,就不会发生候选Bean冲突的问题。

使用@Qualifier或@Primary注解仅仅是在你不想用默认别名来命名注入的bean或是忘记了使用默认别名的情形。

当我们不使用默认别名来使用自动注入功能,我们就需要使用@Qualifier来指定选择的类型,像下面这样:

注意,如果想将ChineseTeacher注入到teacher对象中,就必须给ChineseTeacher类设置别名。

@Service、@Component等注解都可以传入一个字符串作为类的别名。

注意:使用@Qualifier注入bean的时候,它所选取的类的别名需要与具体的类的别名一致,否则会报无法找到指定类型的错误。

 总结

罗里吧嗦说了这么多,其实总结起来很简单。

我们自动注入的时候,如果有多个候选实现类的bean,spring boot启动的时候就不知道该选择哪个bean进行注入,因此会报错。

使用@Primary可以指定一个首选Bean注入;使用@Qualifier可以在自动注入的地方通过传入一个限定名(也就是类的别名)来选取指定的实现类,只不过必须与类的别名一致(如果不传限定名,就使用类的默认别名)

如果既不用@Primary也不用@Qualifier,那就必须在自动注入的时候直接以类的默认别名来命名。

给(spring ioc容器管理的)类设置别名的方式是:@Service("别名")、@Component("别名") 、@Bean("别名") 等等。

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spring中的@Primary和@Qualifier是两个常用的注解,用于解决当有多个同类型的bean需要注入时的歧义问题。 @Primary注解用在bean的定义上,表示该bean是优先选择的bean。当有多个同类型的bean需要注入时,Spring会优先选择被@Primary注解标记的bean作为注入的对象。 @Qualifier注解用在注入点上,可以和@Autowired、@Resource等注解一起使用,用来指定具体要注入的bean的名称。通过在@Qualifier中指定bean的名称,可以明确告诉Spring要选择哪个bean进行注入。 举个例子来说明,假设有一个接口类型的bean,下面有两个实现类A和B都实现了这个接口,并且都被Spring管理。 当我们在其他地方需要注入这个接口类型的bean时,如果不使用@Qualifier和@PrimarySpring会产生歧义,无法确定注入哪个实现类的对象。 使用@Primary注解,我们可以在实现类A上标注@Primary,表示A是优先选择的bean。 当需要注入接口类型bean时,Spring会自动选择A作为注入的对象。 使用@Qualifier注解,我们可以在注入点上标注@Qualifier,然后在@Qualifier中指定具体要注入的bean的名称。 比如,可以使用@Qualifier("beanA")明确指定要注入的bean是A。 以上就是@Primary和@Qualifier的基本用法和含义,通过使用这两个注解可以很方便地解决多个同类型bean的注入问题。 ### 回答2: spring中的@Primary和@Qualifier是依赖注入中的两个注解。 @Primary注解用于标注一个类为首选的bean。当有多个类型相同的bean存在时,spring将会优先选择被@Primary注解标注的bean进行注入。 @Qualifier注解可以与@Autowired一起使用,用于解决存在多个类型相同的bean时的歧义性。通过为@Autowired指定@Qualifier注解的value属性,可以指定具体注入哪个bean。 例如,假设我们有一个接口Person,有两个实现类:Student和Teacher。如果我们在Spring配置文件中同时注册了这两个bean,那么在注入Person类型的依赖时就会有歧义。此时,我们可以使用@Primary注解为其中一个实现类标注为首选bean。这样,在需要注入Person类型的地方,spring就会优先选择被@Primary注解标注的实现类进行注入。 另一种情况是,如果我们不想使用@Primary注解来标注首选bean,而是希望根据特定的条件进行选择注入,就可以使用@Qualifier注解。@Qualifier注解需要与@Autowired注解一起使用,通过指定value属性来指定注入哪个bean。比如,我们可以在@Autowired注解后添加@Qualifier("student")来指定注入的是Student类型的bean。 通过@Primary和@Qualifier注解,我们可以在存在多个类型相同的bean时,精确控制注入的对象,避免歧义性。 ### 回答3: Spring是一个开源的Java框架,提供了依赖注入(Dependency Injection)的功能。在Spring中,我们可以使用@Primary和@Qualifier注解来处理多个相同类型的实例。 @Primary注解用于标识在多个相同类型的Bean中,哪个Bean应该作为首选的Bean。当我们不使用@Qualifier注解指定具体的Bean时,Spring会自动选择使用带有@Primary注解的Bean。例如,当我们有多个实现了同一个接口的类时,通过使用@Primary注解,我们可以指定一个类作为主要实现。 @Qualifier注解用于在多个相同类型的Bean中选择特定的Bean。当我们有多个相同类型的Bean需要注入时,在使用@Autowired或@Inject注入时,我们可以使用@Qualifier注解指定具体的Bean。@Qualifier注解的参数可以是Bean的名字或者是自定义的标识符。 举个例子来说,假设我们有一个接口Animal,有两个实现类Dog和Cat。如果我们希望将Cat作为首选的实现类,我们可以在Cat类上使用@Primary注解。如果有一个需要注入Animal类型的类,但我们想注入Dog,我们可以在注入的地方使用@Qualifier("dog")注解来指定具体的Bean。 总之,@Primary注解用于标识首选的Bean,@Qualifier注解用于指定特定的Bean。它们可以一起使用来处理多个相同类型的实例,使得依赖注入更加灵活和精确。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值