今天上厕所的时候刷到别人说到面向接口编程和面向业务编程,然后就想到了接口的特性,随后想到一个接口可以有多个实现类,有多个实现类的话,控制层是怎么调用其中的实现类的呢?因为以前没遇到过这个问题,自己的实际开发中一个接口只有一个实现类,然后就想到万一一个接口有两个以上的实现类的话,控制层自动注入的实现类到底是哪一个的问题。
(然后还想到,自己写的每一个项目,都是一个接口一个实现类,根本没有利用到接口设计的优点,当然这不是本题所讨论的重点,但是可以做个小标记供以后进阶学习。)

下面开始介绍我网上搜集到的三种方式。


一、直接New

这个没什么好说的,在controller层注入service的时候,直接把相应的实现类new出来。
但是直接new的话就失去了spring管理bean的优点,这种方法当然不可取,但是从理解层面是最简单暴力的。

二、使用@Qualifier注解

StudentService接口有两个实现类StudentServiceImpl和TestImpl
在这个StudentController中注入TestImpl这个实现类可以在@Autowired下加上@Qualifier注解来选择你想注入的实现类。

@RestController
@RequestMapping(value = "/student")
public class StudentController {

    @Autowired
    @Qualifier("TestImpl")
    StudentService studentService;
    ...

同时别忘了在你的TestImpl代码上的@Service注解里写上TestImpl

@Service("TestImpl")
public class TestImpl implements StudentService {

同时正版的serviceImpl的@Service注解也应该写上相应的别名

@Service("StudentServiceImpl")
public class StudentServiceImpl implements StudentService {

为什么叫@Service注解里的内容是别名呢,点开它的源码你就知道了(文档注释可以翻译来看)
在这里插入图片描述
然后你再点开@Qualifier的源码,你就知道个大概了
在这里插入图片描述
所以你只要给你的实现类上写上别名,然后在控制层用@Qualifier注解,想注入哪个实现类就注入哪个实现类。

三、使用@Resource注解

使用该注解同样要在实现类上的@Service注解里写上别名

@RestController
@RequestMapping(value = "/student")
public class StudentController {

    @Resource(name = "TestImpl")
    StudentService studentService;
    ...

点进它的源码可以发现它不是springframework包下的注解,而是javax.annotation包下的。其中有什么知识点后面再查。
其中在它的源码里可以看到有两个字段name和type,从字面上就可以理解到是两种注入方式byname和bytype。 反正该方法可以实现注入指定的实现类,关于它本身的详细知识可以再自行学习,下面有我查的参考链接。



后感:其实之前在学习SpringBoot的时候遇到过@Qualifier和@Resource注解,当时似懂非懂,后来又遇到了,也去查了,特别是@Qualifier,应该是查过几次,但是应该每次都似懂非懂,就出现这种后来碰到它又不会的状态。所以结合实际问题来学习还是能掌握的牢固一些。今后应该是不会再忘记@Qualifier的用法了。



最后祝大家变得更强~


参考链接:https://www.cnblogs.com/xiaozhengtongxue/p/13736829.html
https://blog.csdn.net/tengdazhang770960436/article/details/38091081
https://blog.csdn.net/weixin_38237873/article/details/83650429

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐