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