深入浅出springboot2.x(3)

依赖注入

前面讲了将bean装配到IOC容器中,但是对于bean之间的依赖没有涉及,在springioc概念中,我们将其称为依赖注入(Dependency Injection,DI)
代码案例,首先定义两个接口,一个人类一个动物

public interface Person {
    public void service();
    public void setAnimal(Animal animal);
}
public interface Animal {
    public void use();
}

两个实现类

@Component
public class BussinessPerson implements Person {
	@Autowired
    private Animal animal= null;
    @Override
    public void service() {
        this.animal.use();
    }

    @Override
    public void setAnimal(Animal animal) {
        this.animal=animal;
    }
}
@Component
public class Dog implements Animal {
    @Override
    public void use() {
        System.out.println("狗"+Dog.class.getSimpleName()+"是人类的朋友");
    }
}

注解 @Autowired是我们常见的注解之一,它会根据属性的类型去找到对应的bean进行注入。Dog类是动物的一种,IOC容器会把dog的实例注入BussinessPerson中。通过IOC容器获取BussinessPerson实例的时候就能够使用Dog实例来提供服务了。测试代码

@ComponentScan
public class DIConfig {

    public static void main(String[] args) {
        ApplicationContext ctx = new AnnotationConfigApplicationContext(DIConfig.class);
        Person p = ctx.getBean(BussinessPerson.class);
        p.service();
    }
}

输出结果

狗Dog是人类的朋友

@ComponentScan注解后面没有写扫描的范围,默认是扫描当前包下的bean。

注解 @Autowired

@Autowired注解是我们常用的注解之一,它注入的机制最基本的一条是根据类型,在IOC容器中我们是用getBean方法获取对应bean的,而getBean支持根据类型或根据名称获取。接着上面的例子,我们再创建一个动物类----猫

@Component
public class Cat implements Animal {
    @Override
    public void use() {
        System.out.println("猫"+Cat.class.getSimpleName()+"抓老鼠");
    }
}

我们还用之前的BussinessPerson类,不过需要注意的是这个类只定义了一个动物属性,而我们现在装配在IOC容器中的有两个动物,运行之前的测试代码:

七月 01, 2019 11:06:53 上午 org.springframework.context.support.AbstractApplicationContext refresh
警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException:
 Error creating bean with name 'bussinessPerson': Unsatisfied dependency expressed through field 'animal'; 
 nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 
 'springbootall.springboot.spring.springdi3_3.Animal' available: expected single matching bean but found 2: cat,dog

从日志中可以看出,IOC容器并不知道你需要注入什么动物给BussinessPerson类对象,从而引发错误。假设目前我们需要的是猫类,那么需要转换一下属性名,把原来的

	@Autowired
    private Animal animal= null;

修改为

	@Autowired
    private Animal cat;

我们再测试的时候看到的就是猫提供的服务。 @Autowired会根据类型找到对应的bean,如果对应的类型的bean不是唯一的,那么它会根据其属性名称和bean的名称进行匹配。如果匹配的上,就会使用该bean,如果还是无法匹配,就会抛异常。

你可能感兴趣的:(深入浅出springboot2.x(3))