03.依赖注入

IoC

在 Spring 中,常常用到控制反转(IoC),而这个概念的理解恰恰是最困难的部分:控制反转中,“反转”的概念在于,将对象的控制权由代码本身移交给容器,过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。多数时候,控制反转也叫依赖注入(DI),(虽然控制反转的实现不止依赖注入一种,还有其它方式如依赖查找等)

依赖注入的方法是:

  • 如果类 X 的一个实例对象 x 调用了类 Y 的一个实例对象 y 的方法,那么就称类 X 依赖于类 Y。为了打破这种依赖——“反转”,首先我们可以引入一个接口 I(第三方类),接口 I 中声明了对象 y 将被对象 x 调用的所有方法;然后,我们对类 Y 稍加改造,使其实现接口 I;最后,我们把在对象 x 中对 y 的调用改为对接口 I 中对应方法的调用。经过这番改造后,原先的 X 对 Y 的依赖关系不存在了,类 X 和 Y 现在都依赖于接口 I。
  • 这种通过引入接口 I 来消除类 X 对 Y 的依赖的方法,被称作“控制反转”,又叫做“依赖注入”。
  • 需要注意的是,类 Y 可能还依赖于其他类。在应用反转之前,X 依赖于 Y,从而也间接依赖于 Y 所依赖的所有“其他类”。应用控制反转之后,不仅消除了 X 对 Y 的直接依赖,且前面提到的那些所有的间接依赖也消除了。而新引入的接口 I 则不依赖于任何类。

一般控制反转分为 3 类:

  • Type 1 : 基于接口(interface injection)。Depending object 需要实现(implement) 特定 interface 以供框架注入所需对象。
  • Type 2 : 基于设值函数(setter injection)。Depending object 需要实现特定 setter 方法(但不需要依赖特定 interface),
  • Type 3 : 基于构造函数(constructor injection)

套用 Laravel 中的名词,Spring 中的 ApplicationContext 本身就是起到了一个服务容器的作用,所有在 ApplicationContext 中注入的 Bean 会由 Spring 自动构造,并且根据@AutoWired 关键字自动的注入到各个类的成员中。