[Spring] DI 依赖注入和 IoC 容器
DI 依赖注入
下面 Person 类依赖 Weapon 类,在我们使用 Person 类,也就是在 new Person
类时也会去 new Weapon
类。
如果遇到后面更换 Weapon 类,需要修改 Person 里面的 new Weapon
。想象一下如果还有其他类也依赖了 Weapon,岂不是都要修改。
public class Person {
private Weapon weapon;
Person() {
weapon = new Weapon("弓箭");
}
public void attack() {
weapon.attack();
}
}
public class Weapon {
private String name;
public Weapon(String name) {
this.name = name;
}
public void attack() {
System.out.println("使用" + this.name + "攻击目标!");
}
}
这就是依赖耦合度过于紧密,解决办法就是通过构造函数注入、或者通过 setter 函数注入。在调用层那边注入 Person 类所需要的类。
public class Person {
private Weapon weapon;
public Person(Weapon weapon) {
this.weapon = weapon;
}
public void attack() {
weapon.attack();
}
}
在 Spring Boot 中,通过注解 @Autowired
、@Resource
、或者 setter 函数就可以注入对象;或者通过构造函数注入。前提是你这个类头上有一个 @Component
、@Service
、或者 @Controller
等注解,也就是类已经被当做一个 Bean 注册到 Ioc 容器了。
IoC 容器
Weapon weapon = new Weapon("弓箭");
Person person = new Person(weapon);
将这些对象装进一个容器里面,这些对象称之为 Bean,容器称之为 IoC。通过 getBean
获取对象,就好比食堂,吃的都在窗口,人们排队到对应窗口打饭就好,窗口后厨只管生产食物。
即,Ioc 容器要做的事情就是自动把项目中要注入的对象自动 new 到容器里面,IoC 容器自动把每一个对象中所依赖的那个对象注入进去。
一个类头上标注了 @Component
、@Service
、或者 @Controller
就会被注册到 IoC 容器。类中有构造函数、@Autowired
、@Resource
、或者 setter 函数就会自动从容器中注入对象。
总结
DI 依赖注入解决了对象依赖的耦合度,IoC 容器可以解决我们注入对象时手动 new 的过程。