Spring的核心机制-依赖注入和控制反转
依赖注入的概念
Spring的核心机制就是IoC(控制反转)容器,IoC的另外一个称呼就是依赖注入(DL)。这两个称呼是从两个角度描述的同一个概念。
IoC是一个重要的面向对象编程的法则,用来消减计算机程序的耦合问题,也是轻量级的Sping框架的核心。
通过依赖注入,应用中的各种组件不需要以硬编码的方法进行耦合,当一个Java实例需要其他Java实例时,系统自动提供需要的实例,无需程序显示获取。
因此,依赖注入实现了组件之间的解耦。
依赖注入和控制反转含义相同,当某个Java对象(调用者)需要调用另一个Java对象(被调用者,即被依赖对象)时,
传统的方法是由调用者采用"new 被调用者"的方式来创建对象,这种方式会导致调用者和被调用者之间的耦合性增加,对项目的后期升级和维护不利。
在使用Spring框架之后,对象的实例不再由调用者创建,而是由Spring容器来创建,Spring容器会负责控制程序之间的关系,而不是由调用者的程序代码直接控制。
这样,可控制权由应用程序代码转移到了Spring容器,控制权发生了反转,这就是Spring的控制反转。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量,这就相当于为调用者注入了它依赖的实例,这就是Spring的依赖注入。
Spring提倡面向接口的编程,依赖注入的基本思想是:明确定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运行。
依赖注入的类型
依赖注入的作用就是使用Spring框架创建对象时,动态地将其所依赖的对象注入到Bean组件中。
其实现主要有两种方式,一种是构造方法注入,另一种是属性setter方法注入。
构造方法注入。是指Spring容器使用构造方法注入被依赖的实例,构造方法可以是有参数或者无参数的。
在大多数情况下,我们都是通过构造函数来创建对象,Spring也可以采用反射的方式,通过使用带参数的构造方法来完成注入,每个参数代表一个依赖,这就是构造方法注入的原理。
使用setter方法注入时,Spring通过JavaBean的无参构造方法来实例化对象。当编写带参数构造方法后,JAVA虚拟机不会再提供默认的无参构造方法。
为了保证使用的灵活性,建议自行添加一个无参构造方法。
属性setter方法注入。属性setter方法注入是指Spring容器使用setter方法注入被依赖的值或者对象,是常见的一种依赖注入方式,这种注入方式具有高度灵活性。
属性setter方法注入要求Bean提供一个默认的构造方法,并为需要注入的属性提供对应的setter方法。
Spring先调用Bean的默认构造方法实例化Bean,然后通过反射的方式调用setter方法注入属性值。
两种注入方式的对比
使用setter方法时,与传统的JavaBean写法更类似,程序员更容易了解和接受,通过setter方法设定依赖关系显得更加直观、自然。
对于复杂的依赖关系,如果采用构造方法注入,会导致构造器过于臃肿,难以阅读。尤其是在某些属性可选的情况下,多参数的构造器更加笨重。
构造方法注入可以在构造器中决定依赖关系的注入顺序,当某些属性的赋值操作有先后顺序时,这点尤为重要。
对于依赖关系无需变化的Bean,构造方法注入更加有用。如果没有setter方法,所有的依赖关系全部在构造器内设定,后续代码不会对依赖关系产生破坏。