您现在的位置是:首页 > 正文

java 接口bean_详解Spring中接口的bean是如何注入的

2024-02-01 00:52:14阅读 2

Question:

这个问题困扰了我好久,一直疑问这个接口的bean是怎么注入进去的?因为只看到使用@Service注入了实现类serviceImpl,使用时怎么能获取的接口,而且还能调用到实现类的方法,难道这个接口是在什么时候自动注入了进去,且和实现类关联上了?

接口

public interface TestService {

public String test();

}

实现类impl

@Service

public class TestServiceImpl implements TestService {

@Override

public String test() {

return “TestServiceImpl”;

}

}

Controller的调用:

@RestController

public class TestCtl {

@Autowired

private TestService testService;

@RequestMapping(“/test”)

public String test() {

return testService.test();

}

}

请求结果:

在这里插入图片描述

Answwer:

后来才知道,并没有注入接口的bean,只注入了实现类serviceImpl的bean,接口只是用来接收的。

这里就要说到@Autowired/@Resource的注入原理了:@Autowired是Spring的注解,Autowired默认先按byType,如果发现找到多个bean,则,又按照byName方式比对,如果还有多个,则报出异常;@Resource 是JDK1.6支持的注解,默认按照名称(Byname)进行装配, 如果没有指定name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

再来说Controller获取实例的过程:使用@Autowired,程序在spring的容器中查找类型是TestService的bean,刚好找到有且只有一个此类型的bean,即testServiceImpl,所以就把testServiceImpl自动装配到了controller的实例testService中,testService其实就是TestServiceImpl实现类;

如果使用的是@Resource,则是先在容器中查找名字为testService的bean,但并没有找到,因为容器中的bean名字是TestServiceImpl(如果@Service没指定bean的value属性,则注入bean的名字就是类名,如果指定了则是指定的名字),然后再通过类型查找TestService类型的bean,找到唯一的了个TestService类型bean(即TestServiceImpl),所以就自动装配实例成功了。更多面试题,欢迎关注公众号Java面试题精选

Note:

byName 通过参数名 自动装配,如果一个bean的name 和另外一个bean的 property 相同,就自动装配。

byType 通过参数的数据类型自动自动装配,如果一个bean的数据类型和另外一个bean的property属性的数据类型兼容,就自动装配

效率上来说@Autowired/@Resource差不多,不过推荐使用@Resource一点,因为当接口有多个实现时@Resource直接就能通过name属性来指定实现类,而@Autowired还要结合@Qualifier注解来使用,且@Resource是jdk的注释,可与Spring解耦。

Question:

如果一个接口有多个实现类时,通过注解获取实例时怎么知道应该获取的是哪一个实现类serviceImpl呢?

再增加了一个实现类TestServiceImpl2

@Service

public class TestServiceImpl2 implements TestService {

@Override

public String test() {

return “TestServiceImpl2”;

}

}

Answer:

多个实现类的话可通过以下2种方式来指定具体要使用哪一个实现:

1、 通过指定bean的名字来明确到底要实例哪一个类

@Autowired 需要结合@Qualifier来使用,如下:

@Autowired

@Qualifier(“testServiceImpl”)

private TestService testService;

@Resource可直接通过指定name属性的值即可,不过也可以使用@Qualifier(有点多此一举了…)

@Resource(name = “testServiceImpl”)

private TestService testService;

@Resource如果不显示的指定name值,就会自动把实例变量的名称作为name的值的,所以也可以直接这样写:

@Resource

private TestService testServiceImpl;

2、 通过在实现类上添加@Primary注解来指定默认加载类

@Service

@Primary

public class TestServiceImpl2 implements TestService {

@Override

public String test() {

return “TestServiceImpl2”;

}

}

这样如果在使用@Autowired/@Resource获取实例时如果不指定bean的名字,就会默认获取TestServiceImpl2的bean,如果指定了bean的名字则以指定的为准。

Question:

为什么非要调用接口来多此一举,而不直接调用实现类serviceImpl的bean来得简单明了呢?

Answer:

1、 直接获取实现类serviceImpl的bean也是可以的;

2、 至于加一层接口的原因:一是AOP程序设置思想指导,给别人调用的接口,调用者只想知道方法和功能,而对于这个方法内部逻辑怎么实现的并不关心;二是可以降低各个模块间的关联,实现松耦合、程序分层、高扩展性,使程序更加灵活,他除了在规范上有卓越贡献外,最精髓的是在多态上的运用;继承只能单一继承,接口却可以多实现

3、 当业务逻辑简单,变更较少,项目自用时,省略掉接口直接使用实现类更简单明了;反之则推荐使用接口;

总结

到此这篇关于详解Spring中接口的bean是如何注入的文章就介绍到这了,更多相关Spring接口的bean注入内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
————————————————
版权声明:本文为CSDN博主「泡泡桔子」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_34184444/article/details/114804242

网站文章

  • Tomcat的使用

    Tomcat的使用

    Tomcat下载tomcat官网:http://tomcat.apache.org安装直接将下载的tomcat压缩包解压即可*注意:此处建议不要安装在有空格或中文目录下卸载直接将解压的文件删除即可目录解析(apache开源项目通用结构)bin 可执行文件conf 配置文件lib 依赖j...

    2024-02-01 00:52:06
  • P4145 上帝造题的七分钟2 / 花神游历各国 (线段树区间开方)

    题目链接:点击这里 题目大意: 给定一个长度为 nnn 的序列 a1,a2,...,ana_1,a_2,...,a_na1,a2,...,an ,对序列进行区间开方和区间查询 题目分析: 因为 1≤a...

    2024-02-01 00:51:59
  • 使用标准输出流(system.out)和打印流 (PrintWriter)来读取txt文件

    在电脑某盘根目录下放一个文本文件.里面写一首诗(内容随意发挥).把诗的内容输出到控制台. 要求: 1.使用标准输出流(system.out)来做。 2.使用打印流; (PrintWriter)来做。 import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReade

    2024-02-01 00:51:29
  • js:输出指定范围内所有自幂数

    4.输出指定范围内所有自幂数

    2024-02-01 00:51:21
  • 解决计算机不能登陆银行网银、邮箱、支付宝、淘宝等问题

    <br />  解决计算机不能登陆银行网银、邮箱、支付宝、淘宝等问题,本人使用了网上多个版本,以下操作才是王道,其余的诸如,重新启动“shell。dll”等,均不能解决,而且降低电脑的安全性。<br /> <br />  开始-运行-输入regsvr32 jscript.dll-确定,然后注册regsvr32 vbscript.dll。

    2024-02-01 00:51:13
  • 移植net-snmp到GSC3280

    移植net-snmp到GSC32801. 概念SNMP 是专门设计用于在 IP 网络管理网络节点(服务器、工作站、路由器、交换机及 HUBS 等)的一种标准协议,它是一种应用层协议。 SNMP 使网络管理员能够管理网络效能,发现并解决网络问题以及规划网络增长。通过 SNMP 接收随机消息(及事件报告)网络管理系统获知网络出现问题。SNMP 管理的网络有三个主要组成部分:管理的设备、代理...

    2024-02-01 00:50:43
  • A5平台eMMC协议分析

    A5平台eMMC协议分析

    目录1.A5平台资源定义1.1 A5平台支持的eMMC协议1.2 8bit方块图1.3 4bit方块图1.4 应用方块图2.eMMC协议2.1术语2.2总线协议2.3 总线模式 3.命令类型3.1命令...

    2024-02-01 00:50:39
  • 用C++实现指数拟合方程的算法

    要用 C 语言实现指数拟合方程的算法,需要按照以下步骤进行: 确定所需的数据。指数拟合方程需要的数据包括至少两组数据,每组数据包含一个自变量和一个因变量。自变量是指可以改变的量,因变量是指随自变量改变...

    2024-02-01 00:50:30
  • 多线程编程-- 线程安全的queue II

    上一篇文章中使用std::mutex 和 条件变量 std::condition_variable 实现了一个线程安全的队列。这个队列是没有边界的, 也就是允许插入无限多的元素的,事实上这是不可能的, 当元素过多时候,插入元素会失效。这是很危险的一种行为。下面来实现一个有边界的线程安全的队列 BoundedBlockingQueuetemplate <typename T>class Bounde

    2024-02-01 00:50:24
  • 英飞凌 AURIX TC3xx 烧录程序后没有反应

    英飞凌 AURIX TC3xx 烧录程序后没有反应

    英飞凌 AURIX TC3xx 烧录程序后没有反应,修改芯片UCBs信息中起始地址与代码中的入口地址相对应

    2024-02-01 00:49:55