默认根据类型,匹配不到则根据bean名字

1.声明一个service接口

public interface HelloService {
void sayHello();
}

2.service接口的实现类,此时bean名字是 helloServiceImpl

@Service
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("say hello impl");
}
}

3.增加一个Controller,注入service

// 生成一个bean,名字为 helloController
@Controller
public class HelloController {
@Autowired
private HelloService helloService; public void hello() {
helloService.sayHello();
}
}

4.测试①:

public class AppTest {

    public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloController controller = (HelloController) context.getBean("helloController");
controller.hello();
}
}

结果如下

成功将Service层的实现类注入到Controller层中,可以把步骤3 代码修改一下

// 生成一个bean,名字为 helloController
@Controller
public class HelloController {
@Autowired
private HelloService abc; public void hello() {
abc.sayHello();
}
}

结果也是可以的,因为@Autowired 第一是按照类型去匹配的,此时IoC容器中HelloService 接口只有一个实现类,所以属性名字怎么写都没关系,都可以注入进去

测试②:增加一个实现类,此时bean名字是 newServiceImpl

@Service
public class NewHelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("new say hello impl");
}
}

现在IoC容器中有两个 HelloService接口的实现类,继续运行测试方法,结果为

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'helloController':
Unsatisfied dependency expressed through field 'abc';
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.convict.service.HelloService' available:
expected single matching bean but found 2: helloServiceImpl,newHelloServiceImpl

因为一个接口有多个实现,所以@Autowired 就按照属性名字去找,即找一个名字为 abc的bean注入,然而IoC容器不存在一个名字叫abc的 bean,因此报错,把属性名改为下面任意一种就可以匹配到了

// 生成一个bean,名字为 helloController
@Controller
public class HelloController {
@Autowired
private HelloService helloServiceImpl; @Autowired
private HelloService newHelloServiceImpl; public void hello() {
helloServiceImpl.sayHello();
newHelloServiceImpl.sayHello();
}
}

测试③:

那我就要把属性名叫 abc,同时有多个实现,而且还能注入,那么在声明组件的时候取个名字就好了,比如

@Service("abc")
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello() {
System.out.println("say hello impl");
}
}

然后Controller 注入的还是abc,结果注入成功

// 生成一个bean,名字为 helloController
@Controller
public class HelloController {
@Autowired
private HelloService abc; public void hello() {
abc.sayHello();
}
}

测试④:

属性名叫 abc,同时有多个实现,同时可以注入,且不在注解处声明bean 的名字,那么这时候使用新的注解@Qualifier 配合@Autowired 一起使用

// 生成一个bean,名字为 helloController
@Controller
public class HelloController {
@Autowired
@Qualifier("helloServiceImpl")
private HelloService abc; public void hello() {
abc.sayHello();
}
}

@Qualifier是指定 一个bean的名字

总结:

1.一个接口只有一个实现的情况下,属性名字怎么写都无所谓,因为按照类型匹配就只有一个bean

2.一个接口多个实现的情况下:

  ① 属性名字跟组件名字一致,组件名字可以在声明的时候指定,比如 @Service("abc")

  ② 属性名字跟组件名字不一致,配合@Qualifier 注解指定组件名字

Spring中@Autowired 注解的注入规则的更多相关文章

  1. Spring中@Autowired注解、@Resource注解的区别 (zz)

    Spring中@Autowired注解.@Resource注解的区别 Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@ ...

  2. Spring中@Autowired注解与自动装配

    1 使用配置文件的方法来完成自动装配我们编写spring 框架的代码时候.一直遵循是这样一个规则:所有在spring中注入的bean 都建议定义成私有的域变量.并且要配套写上 get 和 set方法. ...

  3. Spring中Autowired注解,Resource注解和xml default-autowire工作方式异同

    前面说到了关于在xml中有提供default-autowire的配置信息,从spring 2.5开始,spring又提供了一个Autowired以及javaEE中标准的Resource注释,都好像可以 ...

  4. Spring中 @Autowired注解与J2EE@Resource注解的区别

    在开发中经常使用到@Autowired和@Resource进行装配. 不禁好奇这两个注解的差异在何处??? 相同点: @Resource的作用相当于@Autowired,均可标注在字段或属性的sett ...

  5. Spring中@Autowired注解、@Resource注解的区别

    Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource.@PostConstruct以及@PreDestroy. @Resour ...

  6. 转:Spring中@Autowired注解、@Resource注解的区别

    Pay attention: When using these annotations, the object itself has to be created by Spring context. ...

  7. Spring中的注解配置-注入bean

    在使用Spring框架中@Autowired标签时默认情况下使用 @Autowired 注释进行自动注入时,Spring 容器中匹配的候选 Bean 数目必须有且仅有一个.当找不到一个匹配的 Bean ...

  8. @Resource或者@Autowired作用/Spring中@Autowired注解、@Resource注解的区别

    @Resource或者@Autowired作用不用写set get就能注入,当然,前提是你已经开启了注解功能. spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定 ...

  9. Spring中 @Autowired注解与@Resource注解的区别

    Spring中 @Autowired注解与@Resource注解的区别在Spring 3.X中经常使用到@Autowired和@Resource进行装配.这两个注解的差异在何处???相同点:@Reso ...

随机推荐

  1. python自动化测试框架的unittest与pytest前后置条件的区别

    前言: 笔者先试有用过unittest的前后置条件和pytest的前后置条件,觉得pytest的前后置条件比unittest的要简洁.方便很多.不过在使用unittest的前后置条件时,已经觉得在和每 ...

  2. mybatis-plus实现多表联查

    一.方法一 1.在pojo模块下新建一个VO 包路径用于提供页面展示所需的数据 2.在vo包下新建EmployInfo类,此类继承了Employees类,再把Dept类的数据复制过来 3.在Dao层中 ...

  3. js获取设备内网ip

    可以直接使用,不需要导入其他配置 看代码 1 <script> 2 //获取内网ip 3 var RTCPeerConnection = window.RTCPeerConnection ...

  4. Centos更换阿里云源

    1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2.下载新的CentOS-Base ...

  5. Git 的配置 config

    Git 的配置 config Git 的配置 config config 文件简述 config 文件位置 信息查询 修改 config 文件 编辑配置文件 增加指定配置项 删除指定配置项 自助餐   ...

  6. kubernetes运行应用2之DaemonSet详解

    kubernetes运行应用1之Deployment详解   查看daemonset 如下,k8s自身的 DaemonSet kube-flannel-ds和kube-proxy分别负责在每个结点上运 ...

  7. Android学习笔记5

    SharedPreferenced的使用方法:SharedPreferences 是一个轻量级的存储类,主要是保存一些小的数据,一些状态信息 第一步:初始化         * 获取SharedPre ...

  8. 【记录一个问题】android opencl c++: 不要Context, CommandQueue类的赋值函数

    一开始代码中这样写了: cl::Context ctx = cl::Context(CL_DEVICE_TYPE_GPU, NULL); cl::CommandQueue queue= cl::Com ...

  9. hbase region, store, storefile和列簇,的关系

    先来一张大图. Hbase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写:另外一部分作为BlockCache,主要用于读数据:这里主要介绍写数据的部分,即Mems ...

  10. Servlet三种创建方式

    直接实现 Servlet 接口不太方便,所以 Servlet 又内置了两个 Servlet 接口的实现类(抽象类),分别为 GenericServlet 和 HttpServlet,因此,创建 Ser ...