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

1.声明一个service接口

  1. public interface HelloService {
  2. void sayHello();
  3. }

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

  1. @Service
  2. public class HelloServiceImpl implements HelloService {
  3. @Override
  4. public void sayHello() {
  5. System.out.println("say hello impl");
  6. }
  7. }

3.增加一个Controller,注入service

  1. // 生成一个bean,名字为 helloController
  2. @Controller
  3. public class HelloController {
  4. @Autowired
  5. private HelloService helloService;
  6.  
  7. public void hello() {
  8. helloService.sayHello();
  9. }
  10. }

4.测试①:

  1. public class AppTest {
  2.  
  3. public static void main(String[] args) {
  4. ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
  5. HelloController controller = (HelloController) context.getBean("helloController");
  6. controller.hello();
  7. }
  8. }

结果如下

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

  1. // 生成一个bean,名字为 helloController
  2. @Controller
  3. public class HelloController {
  4. @Autowired
  5. private HelloService abc;
  6.  
  7. public void hello() {
  8. abc.sayHello();
  9. }
  10. }

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

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

  1. @Service
  2. public class NewHelloServiceImpl implements HelloService {
  3. @Override
  4. public void sayHello() {
  5. System.out.println("new say hello impl");
  6. }
  7. }

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

  1. 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,因此报错,把属性名改为下面任意一种就可以匹配到了

  1. // 生成一个bean,名字为 helloController
  2. @Controller
  3. public class HelloController {
  4. @Autowired
  5. private HelloService helloServiceImpl;
  6.  
  7. @Autowired
  8. private HelloService newHelloServiceImpl;
  9.  
  10. public void hello() {
  11. helloServiceImpl.sayHello();
  12. newHelloServiceImpl.sayHello();
  13. }
  14. }

测试③:

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

  1. @Service("abc")
  2. public class HelloServiceImpl implements HelloService {
  3. @Override
  4. public void sayHello() {
  5. System.out.println("say hello impl");
  6. }
  7. }

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

  1. // 生成一个bean,名字为 helloController
  2. @Controller
  3. public class HelloController {
  4. @Autowired
  5. private HelloService abc;
  6.  
  7. public void hello() {
  8. abc.sayHello();
  9. }
  10. }

测试④:

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

  1. // 生成一个bean,名字为 helloController
  2. @Controller
  3. public class HelloController {
  4. @Autowired
  5. @Qualifier("helloServiceImpl")
  6. private HelloService abc;
  7.  
  8. public void hello() {
  9. abc.sayHello();
  10. }
  11. }

@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. CF858D Polycarp's phone book

    题意翻译 有 n 个长度为 9 且只包含数字字符互不相同的串. 需要对于每个串找到一个长度最短的识别码,使得这个识别码当且仅当为这个串的子串. 题目分析 因为范围不是非常大,所以可以将子串筛出来 然后 ...

  2. Pytest_配置文件-pytest.ini(4)

    pytest配置文件可以改变pytest的默认运行方式,它是一个固定的文件名称pytest.ini. 存放路径为项目的根目录 解决中文报错 在讲解配置文件的可用参数前,我们先解决一个高概率会遇到的问题 ...

  3. python与redis交互(4)

    python可以使用redis模块来跟redis交互 redis模块的使用 安装模块: pip3 install redis 导入模块:import redis 连接方式 严格连接模式:r=redis ...

  4. Python_获取全部异常信息

    import traceback try: os.getcwd('exc') except Exception: exc = traceback.format_exc() print(exc)

  5. [ vue ] quasar框架踩坑:在vue文件外导入路由,执行router.push('/')没有效果

    问题描述: 1. 如图所示的项目结构目录, axios.js 文件负责拦截全局请求和回复,我在拦截回复的代码中写了:如果服务器回复了一个401错误,则执行Router.push('/'),但是该方法失 ...

  6. 关闭SpringBoot logo图标

    public static void main(String[] args) {// SpringApplication.run(LicenseApp.class, args); //关闭Spring ...

  7. Linux weblogic

    su ****** (切换weblogic用户,不能用其他) java -jar fmw_12.1.3.0.0_wls.jar 如出现未设置 DISPLAY 环境变量   如果是未知则看看是不是roo ...

  8. Nagios 请检查HTTP服务器关于该CGI的访问权限设置

    无权查看任何主机的信息. 请检查HTTP服务器关于该CGI的访问权限设置. 搜索了一下方法 确保 htpasswd.user的所有组为nagios 解决办法: vi /usr/local/nagios ...

  9. .gitignore文件编写规则

    1.gitignore说明 在使用git的过程中,一般我们总会有些文件无需纳入git的管理,也不希望它们总出现在未跟踪文件列表,这些文件通常是日志文件.临时文件.编译产生的中间文件.工具自动生成的文件 ...

  10. 利用quake捡洞

    quake一开漏洞全靠捡 定位资产 通过主域名定位子域名资产 domain:"target.com" 通过C段定位资产 ip: "1.1.1.1/24" 通过证 ...