目录
1.4.2 消除歧异处理方法1:变量名用cat的装配bean的名称,不是类名
1.4.3 消除歧异处理方法2:cat的装配bean用@Primary标识为优先使用的bean
1.4.4 消除歧异处理方法3:@Qualifer("bean的名称")标注注入哪个bean
1.获取bean
1.1 定义动物和人类接口
人类依靠动物来提供一些服务。
//动物接口
public interface Animal {
//动物的作用
public void usefor();
}
// 人类接口
public interface Person {
// 养了动物
public void setAnimal(Animal animal);
// 动物提供服务
public void animalService();
}
1.2 实现接口,且装配IoC
@Autowired 获取bean
// 狗实现动物接口
@Component
public class Dog implements Animal {
@Override
public void usefor() {
System.out.println("狗可以用来看家");
}
}
// 商人实现人类接口
@Component
public class BusinessPerson implements Person {
@Autowired // Animal是一个接口,IoC注入其实现类的实例
private Animal animal;
@Override
public void animalService() {
animal.usefor();
}
@Override
public void setAnimal(Animal animal) {
this.animal = animal;
}
}
1.3测试获取bean
@SpringBootApplication
public class SpringIoCApplication {
public static void main(String[] args) {
SpringApplication.run(SpringIoCApplication.class, args);
ApplicationContext ac = new AnnotationConfigApplicationContext(PojoConfigBusinessPerson.class);
Person bp = ac.getBean(Person.class);
System.out.print("Person.animalService : ");
bp.animalService();
}
}
输出
Person.animalService : 狗可以用来看家
并且Animal的实例为dog。
可知,注入的是实例,而非接口,接口是不能被注入的。且这个接口有两个实现类时,会抛出异常,测试见下文。
1.4接口有两个实现类的注入问题【bean的歧异】
1.4.1 给Animal增加一个实现类Cat。
//猫实现动物接口
@Component
public class Cat implements Animal {
@Override
public void usefor() {
System.out.println("猫用来捕捉老鼠...");
}
}
启动main方法,抛出异常,因为IoC不知道该注入哪个bean,有歧异。
Field animal in com.zyf.springIoC.pojo.BusinessPerson required a single bean, but 2 were found:
- cat: defined in file [E:\zyf\learn\github\zhangyangfei\springIoC\springIoC\target\classes\com\zyf\springIoC\pojo\Cat.class]
- dog: defined in file [E:\zyf\learn\github\zhangyangfei\springIoC\springIoC\target\classes\com\zyf\springIoC\pojo\Dog.class]
1.4.2 消除歧异处理方法1:变量名用cat的装配bean的名称,不是类名
@Component("catbean")
public class Cat implements Animal
@Autowired // Animal是一个接口,IoC注入其实现类的实例
private Animal catbean;//变量名用cat的装配bean的名称,不是类名
输出: Person.animalService : 猫用来捕捉老鼠...
小结:IoC的getBean先用type,再用name。
1.4.3 消除歧异处理方法2:cat的装配bean用@Primary标识为优先使用的bean
(BusinessPerson恢复原来的写法)
@Component
@Primary //优先权
public class Cat implements Animal
输出: Person.animalService : 猫用来捕捉老鼠...
给Dog加上@Primary,启动也会报错,依旧会歧异。
1.4.4 消除歧异处理方法3:@Qualifer("bean的名称")标注注入哪个bean
@Qualifier("dog")
private Animal animal;
输出:Person.animalService : 狗可以用来看家
@Qualifier和@Primary同时使用,@Qualifier优先级更高。
1.4.5 带有参数的构造函数的bean装配
private Animal animal;
public BusinessPerson(@Autowired @Qualifier("cat") Animal animal){//构造函数
this.animal = animal;
}
输出: Person.animalService : 猫用来捕捉老鼠...
2.总结
2.1 获取bean的类型可以是接口,但是bean是接口实现类的实例,这个实例由springIoC提供。
2.2 不能同时注入两个实例,会产生歧异。需要消除歧异,可以指定bean的名称,可以给一个bean增加优先使用权(@Primary),可以在注入的时候给bean增加一个符合者的指定(@Qualifier)。
2.3 主要通过@Autowired来注入bean。