SpringBoot系列之注解@Autowired VS @Qualifier VS @Primary(五)

前言

我们看到这几篇内容都是掌握基础,避免后续我们做项目时回头重新复习,所以本节我们来讨论下注解@Autowired和@Qualifier的区别所在。

@Autowired VS @Qualifier VS @Primary

首先我们定义如下一个车辆接口,我们知道车辆可以启动和停止,所以在此接口中我们定义这两个方法,如下:

package com.demo.springboot;

public interface Vehicle {
    String start();
    String stop();
}

接下来我们定义汽车和自行车类来实现上述接口,如下:

复制代码
package com.demo.springboot;

import org.springframework.stereotype.Component;

@Component
public class Bike implements Vehicle {
    @Override
    public String start() {
        return "Bike started";
    }

    @Override
    public String stop() {
        return "Bike stopped";
    }
}
复制代码
复制代码
package com.demo.springboot;

import org.springframework.stereotype.Component;

@Component
public class Car implements Vehicle {
    @Override
    public String start() {
        return  "Car started";
    }

    @Override
    public String stop() {
        return "Car stopped";
    }
}
复制代码

接下来我们定义车辆服务类,并调用车辆接口,如下:

复制代码
package com.demo.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {
    
    @Autowired
    private Vehicle vehicle;

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}
复制代码

我们在通过汽车和自行车实现车辆接口,同时通过添加注解@Component来创建bean,接下来我们在创建车辆服务类时通过注解@Autowired来获取Spring IOC容器中的车辆bean,但是此时我们发现车辆接口是不明确的,我们不知道此接口的具体实现到底是汽车还是自行车,所以编译器自动报错如下:

这个时候注解@Qualifier就派上用场了,通过此单词解释也了然,意为限定:如果有多个相同类型的bean,则@Qualifier批注用于解决自动注解@Autowired冲突。 所以我们需要通过注解@Qualifier来明确限定该接口的实例时汽车还是自行车类,这里我们限定为自行车类,如下:

复制代码
package com.demo.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {

    @Autowired
    @Qualifier("bike")
    private Vehicle vehicle;

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}
复制代码

注解@Autowired既可以作用于字段,也可以作用于构造函数,使用注解@Autowired作用于构造函数时,在Spring 4.3版本后(如果我没记错的话)可以省略注解@Autowired,所以我们如上可以等同如下:

复制代码
package com.demo.springboot;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {
    
    private Vehicle vehicle;

    public VehicleService(@Qualifier("bike") Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}
复制代码

如上是我们在使用接口具体实例时使用注解@Qualifier限定,要是针对车辆接口的具体实现汽车和自行车类,我们有一个总是想注入的实现,也就是说在接口具体实现源头就指定而非调用时指定,此时我们应该怎么办呢?此时我们可以使用注解@Primary,如下:

复制代码
package com.demo.springboot;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class Bike implements Vehicle {
    @Override
    public String start() {
        return "Bike started";
    }

    @Override
    public String stop() {
        return "Bike stopped";
    }
}
复制代码
复制代码
package com.demo.springboot;

import org.springframework.stereotype.Service;

@Service
public class VehicleService {

    private Vehicle vehicle;

    public VehicleService(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}
复制代码

想必通过如上简单的例子我们明白了如题三者的使用,我们同样来下一个结论:@Autowired注解使我们能够将依赖项注入bean,当可以按类型能够唯一地找到每个bean时,它无需附加配置就可以很好地工作,但是当我们可以注入多个bean时,我们必须使用注解@Qualifier按名称或注解@Primary指定主体来帮助Spring找到所需的具体实现。 

总结

本节简短的内容我们到此结束,关于一些基本注解的使用和区别到这里就已结束,后续遇到其他的继续通过博文补充,下一节我们将进入Web的旅行,感谢您的阅读,我们下节见。


为了方便大家在移动端也能看到我分享的博文,现已注册个人公众号,扫描上方左边二维码即可,欢迎大家关注,有时间会及时分享相关技术博文。

感谢花时间阅读此篇文章,如果您觉得这篇文章你学到了东西也是为了犒劳下博主的码字不易不妨打赏一下吧,让楼主能喝上一杯咖啡,在此谢过了!
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
本文版权归作者和博客园共有,来源网址:http://www.cnblogs.com/CreateMyself)/欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   Jeffcky  阅读(3210)  评论(1编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2017-01-06 EntityFramework Core Raw SQL
点击右上角即可分享
微信分享提示