Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 551|回复: 0

spring的@primary和@qualifier注解解决一个接口多个实现的注入问题

[复制链接]
  • TA的每日心情
    奋斗
    2024-11-24 15:47
  • 签到天数: 804 天

    [LV.10]以坛为家III

    2053

    主题

    2111

    帖子

    72万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    726782
    发表于 2021-6-7 16:51:22 | 显示全部楼层 |阅读模式

    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注解可以调用到具体实现,相当于一种标识机制。

     

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

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-2 12:42 , Processed in 0.062980 second(s), 30 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表