全注解下的spring IOC之依赖注入

喜欢ヅ旅行 2022-05-13 19:16 262阅读 0赞

主要讲IOC容器如何加载bean之间的依赖关系和bean值得获取。

案例

Person接口

  1. package com.wuk.demo4;
  2. public interface Person {
  3. /*使用动物服务*/
  4. public void service();
  5. /*设置动物*/
  6. public void setAnimal(Animal animal);
  7. }

Animal接口

  1. package com.wuk.demo4;
  2. public interface Animal {
  3. public void use();
  4. }

BusinessPerson 类

  1. package com.wuk.demo4;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class BusinessPerson implements Person {
  6. //该注解会根据属性类型在IOC中找到相对应的对象bean的值并注入
  7. @Autowired
  8. private Animal animal;
  9. @Override
  10. public void service() {
  11. this.animal.use();
  12. }
  13. @Override
  14. public void setAnimal(Animal animal) {
  15. this.animal=animal;
  16. }
  17. }

Dog类

  1. package com.wuk.demo4;
  2. import org.springframework.stereotype.Component;
  3. //表示这个类将被springIOC容器扫描装配
  4. @Component
  5. public class Dog implements Animal {
  6. @Override
  7. public void use() {
  8. System.out.println("狗"+Dog.class.getSimpleName()+"是用来看门的");
  9. }
  10. }

AppConfig 配置类

  1. package com.wuk.demo4;
  2. import org.springframework.context.annotation.ComponentScan;
  3. import org.springframework.context.annotation.Configuration;
  4. //表示它会进行扫描,只扫描该类所在额包和子包
  5. @ComponentScan
  6. //表示这是一个配置文件
  7. @Configuration
  8. public class AppConfig {
  9. }

测试类

  1. package com.wuk.demo4;
  2. import org.springframework.context.ApplicationContext;
  3. import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  4. public class IocTest4 {
  5. public static void main(String[] args) {
  6. ApplicationContext app=new AnnotationConfigApplicationContext(AppConfig.class);
  7. Person person=app.getBean(BusinessPerson.class);
  8. person.service();
  9. }
  10. }

结果

  1. Dog是用来看门的

注解@Autowired

注入的机制是根据类型。
如果我们现在再创建一个Cat类

  1. package com.wuk.demo4;
  2. import org.springframework.stereotype.Component;
  3. //表示这个类将被springIOC容器扫描装配
  4. @Component
  5. public class Cat implements Animal {
  6. @Override
  7. public void use() {
  8. System.out.println("猫"+Cat.class.getSimpleName()+"是用来抓老鼠的");
  9. }
  10. }

如果再执行上述代码,就会报错如下:

  1. Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.wuk.demo4.Animal' available: expected single matching bean but found 2: cat,dog
  2. at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:215)
  3. at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1113)
  4. at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1062)
  5. at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
  6. ... 14 more

现在对BusinessPerson类中的animal修改为dog

  1. package com.wuk.demo4;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.stereotype.Component;
  4. @Component
  5. public class BusinessPerson implements Person {
  6. //该注解会根据属性类型在IOC中找到相对应的对象bean的值并注入
  7. @Autowired
  8. private Animal dog;
  9. @Override
  10. public void service() {
  11. this.dog.use();
  12. }
  13. @Override
  14. public void setAnimal(Animal animal) {
  15. this.dog=animal;
  16. }
  17. }

异常消失。
watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3d1MjM3NDYzMzU4Mw_size_27_color_FFFFFF_t_70
在这里插入图片描述
在这里插入图片描述

消除歧义性-@Primary和@Qualifier

  1. package com.wuk.demo4;
  2. import org.springframework.context.annotation.Primary;
  3. import org.springframework.stereotype.Component;
  4. @Primary
  5. @Component
  6. public class Cat implements Animal {
  7. @Override
  8. public void use() {
  9. System.out.println("猫"+Cat.class.getSimpleName()+"是用来抓老鼠的");
  10. }
  11. }

@Primary就是告诉IOC,当发现多个相同类型的Bean时候,请优先使用我进行注入。
但是问题又来了,如果有多个类上使用@Primary怎么办?

  1. @Qualifier("dog")
  2. @Autowired
  3. private Animal animal;

@Qualifier(“dog”) 这样IOC容器就会根据类型和名称去寻找对应的Bean进行注入。

带有参数的构造方法类的装配

在上述中我们都是基于一种情况,就是在不带参数的构造方法下实现依赖注入。

  1. package com.wuk.demo4;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.beans.factory.annotation.Qualifier;
  4. import org.springframework.stereotype.Component;
  5. @Component
  6. public class BusinessPerson implements Person {
  7. private Animal animal;
  8. public BusinessPerson(@Autowired @Qualifier("dog") Animal animal){
  9. this.animal=animal;
  10. }
  11. @Override
  12. public void service() {
  13. this.animal.use();
  14. }
  15. @Override
  16. public void setAnimal(Animal animal) {
  17. this.animal=animal;
  18. }
  19. }

public BusinessPerson(@Autowired @Qualifier(“dog”) Animal animal)

发表评论

表情:
评论列表 (有 0 条评论,262人围观)

还没有评论,来说两句吧...

相关阅读