• Spring中@Autowired 注解的注入规则


    默认根据类型,匹配不到则根据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 注解指定组件名字

  • 相关阅读:
    柱状图 highcharts 柱状图默认是显示的 Heighcharts.com 的版权。设置去掉不显示(非商业)
    eclipse下使用maven配置库托管jar包
    Java的云打印Lodop
    文本框限制输入类型<input>的输入框
    初次使用JFinal
    【原创】java实现两单链表相加求和
    【原创】Springboot的Filter拦截器中使用@value获取值为null
    【原创】Oracle主从同步---创建物理备份数据库[Creating a Physical Standby Database]
    【原创】基于Telnet协议的Jenkins远程部署
    【原创】FastDFS简单安装配置-----同一台机器测试
  • 原文地址:https://www.cnblogs.com/convict/p/10688335.html
Copyright © 2020-2023  润新知