spring IoC回顾(依赖注入)

@ Autowired

它注入的机制最基本的一条是根据类型( by type ), 我们回顾IoC 容器的顶级接口BeanFactory ,就可以知道IoC 容器
是通过getBean 方法获取对应Bean 的,而getBean 又支持根据类型( by type )或者根据名称( by name )。

如果Dog为Animal的实现类,则通过以下注解可以注入

@Autowired
private Animal animal = null;

但如果同时有Dog,Cat两个实现类,则以上的注入会报错。

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'businessman': Unsatisfied dependency expressed through field 'animal'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.example.springboot.chapter3.Animal' available: expected single matching bean but found 2: cat,dog......

Spring IoC 容器并不能知道你需要注入什么动物(是狗? 是猫? )

修改为:

@Autowired
private Animal dog = null;

我们只是将属性的名称从animal 修改为了dog,那么我们再测试的时候,你可以看到是
采用狗来提供服务的。那是因为@Autowired 提供这样的规则, 首先它会根据类型找到对应的Bean,
如果对应类型的Bean 不是唯一的,那么它会根据其属性名称和Bean 的名称进行匹配。如果匹配得
上,就会使用该Bean :如果还无法匹配,就会抛出异常。
这里还要注意的是@Autowired 是一个默认必须找到对应Bean 的注解,如果不能确定其标注属
性一定会存在并且允许这个被标注的属性为null , 那么你可以配置@Autowired 属性required 为false

@Autowired(required = false)

显然以上的改法是一种憋屈的做法,好好的动物固定成了狗。注解@Primary ,它是一个修改优先权的注解,当我们有猫有狗的时候,假设这次需要使用猫, 那么只需要在猫类的定义上加入@Primarγ 就可以了,

@Component
@Primary
public class Cat implements Animal {
...
}

这里的@Primary 的含义告诉S pring IoC 容器, 当发现有多个同样类型的Bean 时\ 请优先使用
我进行注入,于是再进行测试时会发现,系统将用猫为你提供服务。因为当Spring 进行注入的时候
虽然它发现存在多个动物, 但因为C at 被标注为了@Primarγ ,所以优先采用Cat 的实例进行了注入,
这样就通过优先级的变换使得IoC 容器知道注入哪个具体的实例来满足依赖注入。

然后,有时候@Primary 也可以使用在多个类上,也许无论是~-~i还是狗都可能带上@Primary 注解, 其结果是IoC 容器还是无法区分采用哪个Bean 的实例进行注入, 又或者说我们需要更加灵活的机制来实现注入,那么@ Q ue li fier 可以满足你的这个愿望。它的配置项va lue 需要一个字符串去定义,它将与@ A ut ow ired 组合在一起,通过类型和名称一起找到Bean 。我们知道Bean 名称在Spring IoC容器中是唯一的标识,通过这个就可以消除歧义性了

@Autowired
@Qualifier("cat")
private Animal animal = null;

在上面,我们都基于一个默认的情况,那就是不带参数的构造方法下实现依赖注入。但事实上,
有些类只有带有参数的构造方法,于是上述的方法都不能再使用了。为了满足这个功能,我们可以
使用@Autow ired 注解对构造方法的参数进行注入

@Component
public class Businessman implements Person {

    @Autowired(required = false)
    private Animal dog = null;

//    @Autowired
//    @Qualifier("cat")
    private Animal animal = null;

    public Businessman(@Autowired @Qualifier("dog") Animal animal){
        this.animal = animal;
    }

    @Override
    public void service() {
        this.animal.use();
    }

    @Override
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42218986/article/details/87183279