依赖注入DI与控制反转IOC
依赖注入
- 目的是为了解耦,由容器动态地将某个依赖关系注入到组件之中
- 关键是:“谁依赖谁,为什么需要依赖,谁注入谁,注入了什么。”
控制反转
控制
- 谁控制谁:IOC容器控制对象
- 控制什么:控制了外部资源获取
反转
- 为何是反转:因为由容器帮忙查找及注入依赖对象,对象只是被动地接受依赖对象,所以是反转
实现两个类,一个Person类,一个CleanAir类
public class Person {
CleanAir air;
public Person(CleanAir air) {
this.air = air;
}
public void breath() {
System.out.println(this.air.toString());
}
}
public class CleanAir {
@Override
public String toString() {
return "CleanAir";
}
}
上面这两个类实现了依赖关系,剩下的就是注入了
当CleanAir变成DirtyAir,需要在Person中加入新的类,为了减少强依赖造成地弊端,定义一个Air接口
public class Person {
IAir air;
public Person(IAir air) {
this.air = air;
}
public void breath() {
System.out.println(this.air.toString());
}
}
public interface IAir {
}
public class CleanAir implements IAir {
@Override
public String toString() {
return "CleanAir";
}
}
public class DirtyAir implements IAir {
@Override
public String toString() {
return "DirtyAir";
}
}
使用 @Component 注解 时期加入容器变成组件,使用 @Autowired 将 IAir 类型对象注入 Person 中
CleanAir 与 DirtyAir 都实现了 IAir 接口,如何让 Person类具体注入哪个对象呢?
使用 @Qualifier 关键字进行区分
@Component
public class CleanAir implements IAir {
@Override
public String toString() {
return "CleanAir";
}
}
@Component
public class DirtyAir implements IAir {
@Override
public String toString() {
return "DirtyAir";
}
}
public interface IAir {
}
@Component
public class Person {
IAir air;
@Autowired//对构造函数进行标注
public Person(@Qualifier("dirtyAir") IAir air) {
this.air = air;
}
public void breath() {
System.out.println(this.air.toString());
}
}
创建测试
public class Test01 {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ac.getBean("person");
System.out.println(person);
person.breath();
}
}