Spring中提供了@Primary和@Qualifier注解来解决一个接口多个实现的注入问题。

@Primary注解

Spring中有提供一个@Primary注解,具体的作用是在一个接口有多个实现类的情况下,会默认选择其中一种实现,帮助Spring对象的正常注入。

比如说现在有一个接口UserService,它有两个实现类UserServiceImpl1和UserServiceImpl2,根据依赖倒置的原则,在Spring中注入的对象应该是接口,由接口去调用具体的实现。

// 接口
public interface UserService {
String getUserName();
}
// 实现1
@Service("userServiceImpl1")
public class UserServiceImpl1 implements UserService{
public String getUserName() {
return "张三";
}
}
// 实现2
@Service("userServiceImpl2")
public class UserServiceImpl1 implements UserService {
public String getUserName() {
return "李四";
}
}
// 调用者注入接口对象
@Service("loginServiceImpl")
public class LoginServiceImpl implements LoginService {
@Autowired
private userService; // 通过接口注入实现 public void getLoginUser() {
System.out.pringln("当前登录的用户是:" + userSerivce.getUserName());
}
}

那么现在就有一个问题,因为Spring注入对象的时候默认是根据类型Type来自动注入的,在有两个实现的情况下,Spring无法根据类型选择到底注入哪一个,即接口不知道该调用哪个实现,就会产生检查异常,导致编译不通过。这时候就可以用@Primary来解决这个问题。

// 实现2
@Primary
@Service("userServiceImpl2")
public class UserServiceImpl1 implements UserService {
public String getUserName() {
return "李四";
}
}

用@Primary注解来告诉Spring在不知道该选哪一个具体实现的时候选哪一个。

这个注解可以用在模块拆分的场景。比如说有一个模块A,有一个模块B,模块A和模块B之间通过接口模块进行交互。通过在接口模块中定义接口,模块B实现这个接口,模块A调用这个接口(注入)。这时候,如果把B模块要拆掉不要,那么A模块中注入的时候就找不到具体的实现,就会报检查异常。这时候,可以在接口模块中添加默认实现类,然后在B模块的真正实现类上添加@Primary注解,那么当有B模块的时候就会调用B模块中的实现,没有的话就调用接口模块中的默认实现,也就实现了模块之间的解耦。

@Qualifier注解

Spring也提供一个@Qualifier注解来解决实现冲突的问题。

// 实现1
@Service("userServiceImpl1")
@Qualifier("userServiceImpl1")
public class UserServiceImpl1 implements UserService{
public String getUserName() {
return "张三";
}
}
// 实现2
@Service("userServiceImpl2")
@Qualifier("userServiceImpl2")
public class UserServiceImpl1 implements UserService {
public String getUserName() {
return "李四";
}
}
// 调用者注入接口对象
@Service("loginServiceImpl")
public class LoginServiceImpl implements LoginService {
@Autowired
@Qualifier("userServiceImpl2")
private userService; // 通过接口注入实现 public void getLoginUser() {
System.out.pringln("当前登录的用户是:" + userSerivce.getUserName());
}
}

通过在实现类和注入调用上使用@Qualifier注解可以调用到具体实现,相当于一种标识机制。

"一个人的成长,是从发现自己并没有自己想象的那么重要开始的。"

spring的@primary和@qualifier注解解决一个接口多个实现的注入问题的更多相关文章

  1. ExpandoObject与DynamicObject的使用 RabbitMQ与.net core(一)安装 RabbitMQ与.net core(二)Producer与Exchange ASP.NET Core 2.1 : 十五.图解路由(2.1 or earler) .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    ExpandoObject与DynamicObject的使用   using ImpromptuInterface; using System; using System.Dynamic; names ...

  2. @Autowired 和 @Resource注解, 一个接口有多个实现类的时候Spring注入遇到的问题

    先说下我遇到的问题,有一个接口 CompensationService, 有两个实现类 MusicCompensationStrategyImpl  和  TakeDeliveryCompensati ...

  3. .NET Core中的一个接口多种实现的依赖注入与动态选择看这篇就够了

    最近有个需求就是一个抽象仓储层接口方法需要SqlServer以及Oracle两种实现方式,为了灵活我在依赖注入的时候把这两种实现都给注入进了依赖注入容器中,但是在服务调用的时候总是获取到最后注入的那个 ...

  4. spring in action 学习笔记八:用@Primary 或者@Qualifier消除@Autowired引起的歧义现象

    首先解释一下@Primary和@Qualifier这两个注解的意思:@Primary的意思是在众多相同的bean中,优先使用用@Primary注解的bean.而@Qualifier这个注解则指定某个b ...

  5. 品Spring:能工巧匠们对注解的“加持”

    问题的描述与方案的提出 在Spring从XML转向注解时,为了自身的开发方便,对注解含义进行了扩充(具体参考本号上一篇文章). 这个扩充直接导致了一个问题,就是需要从注解往元注解以及元元注解(即沿着从 ...

  6. net core天马行空系列: 一个接口多个实现类,利用mixin技术通过自定义服务名,实现精准属性注入

    系列目录 1.net core天马行空系列:原生DI+AOP实现spring boot注解式编程 2.net core天马行空系列: 泛型仓储和声明式事物实现最优雅的crud操作 哈哈哈哈,大家好,我 ...

  7. Castle Windsor Ioc 一个接口多个实现解决方案

    介绍 Castle Windsor 是微软的Ioc类库,本文主要介绍解决一个接口多个实现的解决方案 接口和类 以下内容不是真实的实际场景,仅仅是提供解决一个接口多个实现的思路. 业务场景类 先假设有一 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)

    一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...

  9. spring笔记-@Primary注解

    1.问题 当一个接口有2个不同实现时,使用@Autowired注解时会报org.springframework.beans.factory.NoUniqueBeanDefinitionExceptio ...

随机推荐

  1. gRPC+gRPC Gateway+swagger小记

    前言 本文记录了grpc-gateway的简单使用. 定义proto 先来看看最常规的 syntax = "proto3"; package protos; service Gre ...

  2. yolov3和ssd的区别

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/BlowfishKing/article/d ...

  3. 解决:perl: warning: Please check that your locale settings

    问题: perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LAN ...

  4. 使用C#+Edge (Chromium)进行Web自动化测试

    今天看到了VisualStudio中现在已经自带了Web单元测试项目模板,便试了一下,发现还比较好用,它默认的是Selenium实现的,测试组在用Selenium+Python来写过自动化测试,原来它 ...

  5. layui confirm 嵌套使用 (随笔记)

    使用layui confirm时不要使用aspx控件,使用html的button按钮 借用一下 官方例子 layer.confirm('您是如何看待前端开发?', { btn: ['重要', '奇葩' ...

  6. find命令通过排序只保留最新的文件目录

    find /usr/local/canal/logs/example -type d -name "*-*" | sort -nr | awk '{if (NR>=2){pr ...

  7. 「SAP技术」 SAP MM MPN物料的采购初探

    「SAP技术」 SAP MM MPN物料的采购初探 1, MPN物料号与我方正常使用料号物料主数据之间的LINK关系维护 MPN料号 14000005 , 我方料号11000250 , 2,采购信息记 ...

  8. Git的使用(2)

    一.git在不同平台下的安装 (1)在linux上安装 如果以centos为例,可以使用yum安装,如下命令: sudo yum install git 如果你在基于debian的发行版上,尝试使用: ...

  9. MySQL 同一Windows系统上安装多个数据库

    Step 1:拷贝一份MySQL整个安装文件,并拷贝一份 my.ini 文件放置安装目录下,然后修改以下内容.注意 port 不能设置为默认的3306,这里我们设置为3307端口. basedir=C ...

  10. ssh-agent,ssh-add 命令

    centos 6.9 下测试: ssh-agent是一个密钥管理器,运行ssh-agent以后,使用ssh-add将私钥交给ssh-agent保管. eval `ssh-agent -s` ssh-a ...