Spring的@Autowired加到接口上但获取的是实现类的问题
作者:发则韩 发布时间:2023-08-23 21:32:21
@Autowired加到接口上但获取的是实现类
问题
Spring的@Autowired加到接口上但获取的是实现类?
/* 类 @Controller注解,会在spring容器中实例化对象 */
@Controller
public class UserContoller{
@Autowired // 先按类型找,然后按id为属性名去找
private UserService userService;
//为什么他会拿到userServiceImpl?
// @Autowired会帮你按UserService的类型去容器中找唯一bean对象
// 1、容器没有该类型的对象:报错
// 2、容器中有该类型的唯一bean对象,就将该唯一bean对象赋值给该属性
///3、容器中有多个【两个及以上】该类型的唯一bean对象,
// 它会再根据该属性名去容器中找,
// 看看容器中的哪个bean对象的id值和该属性名一致,
// 如果有,就将容器中该对象赋值给该属性,如果没有报错。
}
/* 接口 */
public interface UserService{}
/* 类 @Service注解,会在spring容器中实例化对象 */
@Service
public class UserServiceImpl implements UserService{}
为什么他会拿到userServiceImpl?
@Autowired先按类型找,然后再按id为属性名去找
他会帮你按UserService的类型去容器中找唯一bean对象
1.容器没有该类型的对象:报错
2.容器中有该类型的唯一bean对象,就将该唯一bean对象赋值给该属性
3.容器中有多个【两个及以上】该类型的唯一bean对象,
它会再根据该属性名去容器中找,看看容器中的哪个bean对象的id值和该属性名一致,如果有,就将容器中该对象赋值给该属性,如果没有报错。
然后通过多态的向上转型就赋值成功。等价于之前手动赋值
UserService userService = new UserServiceImpl();
@Autowired一个接口有多个实现类
@Autowired是spring的注解,默认使用的是byType的方式向Bean里面注入相应的Bean。
例如
@Autowired
private UserService userService;
这段代码会在初始化的时候,在spring容器中寻找一个类型为UserService的bean实体注入,关联到userService的引入上。
但是如果UserService这个接口存在多个实现类的时候,就会在spring注入的时候报错,具体如下:
public class UserService1 implements UserService
public class UserService2 implements UserService
当存多个UserService的实现类时,错误信息如下:
2016-08-05 14:53:53,795 ERROR [org.springframework.test.context.TestContextManager] - <Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@14a2f921] to prepare test instance [UserServiceTest@3c87521]>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'UserServiceTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private yjc.demo.service.UserService UserServiceTest.userService; nested exception is he[yjc.demo.service.UserService] is defined: expected single matching bean but found 2: userService1,userService2
抛出了org.springframework.beans.factory.BeanCreationException,而原因是注入的时候发现有2个匹配的bean,但是不知道要注入哪一个:expected single matching bean but found 2: userService1,userService2
那么如何应对多个实现类的场景呢,看一下代码:
@Autowired
private UserService userService1;
@Autowired
private UserService userService2;
@Autowired
@Qualifier(value = "userService2")
private UserService userService3;
@Test
public void test(){
System.out.println(userService1.getClass().toString());
System.out.println(userService2.getClass().toString());
System.out.println(userService3.getClass().toString());
}
运行结果:
class yjc.demo.serviceImpl.UserService1
class yjc.demo.serviceImpl.UserService2
class yjc.demo.serviceImpl.UserService2
运行结果成功,说明了2种处理多个实现类的方法:
1.变量名用userService1,userService2,而不是userService。
通常情况下@Autowired是通过byType的方法注入的,可是在多个实现类的时候,byType的方式不再是唯一,而需要通过byName的方式来注入,而这个name默认就是根据变量名来的。
2.通过@Qualifier注解来指明使用哪一个实现类,实际上也是通过byName的方式实现。
由此看来,@Autowired注解到底使用byType还是byName,其实是存在一定策略的,也就是有优先级。优先用byType,而后是byName。
来源:https://blog.csdn.net/weixin_43575868/article/details/104535986
猜你喜欢
- 本文主要给大家介绍java的InputStream 流的使用。(1)FileInputstream: 子类,读取数据的通道使用步骤:1.获取
- 一、前言在Spring中,事务有两种实现方式:编程式事务管理: 编程式事务管理使用TransactionTemplate可实现更细
- 一、文件的编码package com.study.io;/*** 测试文件编码*/public class EncodeDemo {/***
- 本文实例讲述了Java基于IO流读取文件的方法。分享给大家供大家参考,具体如下:public static void readFile(){
- 前言最近看插件库上少有的取色器大都是圆形的或者奇奇怪的的亚子,所以今天做两个矩形的颜色取色器提示:以下是本篇文章正文内容,下面案例可供参考一
- Google 发布的Material Design支持库,对我们的APP设计有很大的影响,如果重新设计APP,支持库应该直接用V4提升到V7
- java解析json数组最简单的json数组[ { &quo
- 实现要求1、使用Java图形界面组件设计软件,界面如图所示。2、软件能够满足基本的“加、减、乘、除"等运算要求。3、程序代码清晰,
- Java实现PC微信扫码支付做一个电商网站支付功能必不可少,那我们今天就来盘一盘微信支付。微信支付官方网站业务流程:开发指引文档支付服务开发
- 一、Sharding-JDBC简介Sharding-JDBC是Sharding-Sphere的一个产品,它有三个产品,分别是Sharding
- 开发 Web 应用的思路实现一个简单的 JSP/Servlet。搭建创建 Web 应用工程的环境。创建 Web 应用工程。Web 应用工程的
- 第一次进入应用的时候,都会有一个引导页面,引导页面的实现起来也很简单,实现的方式也有很多,下面是自己写的一个引导页面的效果,大致的实现思路为
- 当你在开发flutter应用的时候,有时会需要调用native的api,往往遇到flutter并没有相应的package, 这时候flutt
- 今天重新装了编译器,结果崩无极限,真是日了狗了了。刚刚才知道问题在哪边。好了,说正事,对于ios开发我没接触,不是很了解,百度了半天,差不多
- HashMap和HashTable,这二者的区别经常被别人问起,今天在此总结一下。(一)继承的历史不同public class
- 一、什么是iText?在企业的信息系统中,报表处理一直占比较重要的作用,iText是一种生成PDF报表的Java组件。通过在服务器端使用Js
- 参考:How to catch an Exception from a threadIs there a way to make Runna
- 背景:在Android中按照数据保存的方式,可以分为如下几种Content Provider (用的SQLite实现),SQLite,Sha
- 本文实例讲述了java实现的简单猜数字游戏代码。分享给大家供大家参考。具体代码如下:import java.util.InputMismat
- JdbcTypeInterceptor运行时自动添加 jdbcType 属性 * 签名@Intercepts({