Spring等依赖注入(Dependency Injection、DI)容器则是功能强大的工具箱。某种程度上,God比Spring更优秀,因为它用最简短的代码,言简意赅地说明了God和Spring的相同的本质,即针对接口编程的使能工具。
Martin Fowler有一篇非常著名的文章——简单一个网页的PageRank为7,《IoC容器和依赖注入模式》(Inversion of Control Containers and the Dependency Injection pattern )。在该文中,Martin Fowler把一些创建对象的工具箱如PicoContainer和Spring背后的“模式”,称为DI。既然术语DI已经被业界广为接受,本文将使用Spring DI称呼Spring(的对象创建模块)。本节还将指出Martin Fowler的该文章的不妥之处。
【最后更新2021.3.1 返回目录
3.2.1 Spring DI的注入方式
1.下载Spring Framework
2.单层依赖
对于简单地单层依赖,如Demo→IMan,使用Spring DI显得大炮打蚊子,它与God相比,没有什么优势。
God使用属性配置文件my.properties保存如下键值对:
aMan=chap3.init.Son
而Spring使用XML保存配置文件,如spring1.xml如下。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="aMan" class="chap3.init.Son" />
</beans>
其中<bean>的属性id表示源代码中使用的键,而属性class表示将创建对象的类全名。从例程3-5源代码中可以看出,Spring从(BlueJ项目根目录下的) spring1.xml中获得键aMan的值,并创建其对象。
Spring最引人注目的强大之处,在多层依赖场合得到体现。假定Demo→IMan<= Hubby→IWoman,而IWoman的子类有妈妈/Mom和姐妹/Sister等。
在多层依赖场合,目前的God,在每一层依赖关系中,都需要使用一次。比如说Demo的main方法中使用God创建某个IMan的对象;而Hubby类体中有成员变量IWoman,也需要使用God创建某个相关的IWoman对象。
Spring DI的强大之处,在于Demo→IMan<= Hubby→IWoman…更多的依赖层,Spring能够按照配置文件一次性地创建各层级的对象,Spring DI只需要在Deme中使用一次ApplicationContext,其他对象都按照配置文件中指定的类全名和值进行初始化。站在Demo的位置看,ApplicationContext和God的地位相当,使用两种工具没有多大的区别。但是,站在Hubby的位置看Hubby→IWoman关系,Hubby代码中既没有new某个IWoman,也不像God那样显式地创建某个IWoman,而Spring DI魔术般地就建立了Hubby依赖的某个IWoman对象。
★依赖注入指类A所依赖的对象,(从A的源代码上看)在不知不觉中被创建。
完成依赖注入工作的模块称为依赖注入容器。Spring DI的核心仍为反射+配置文件,这般魔术是如何实现的呢?由于类A不显式地调用依赖注入容器——真正体现容器的注入能力,因此该容器必须首先创建类A以及它依赖的对象如B,再将B赋值给A的某个成员变量。所以,依赖注入工具需要是一个容器以保存A和B的对象。
按照上述依赖注入定义,Spring DI在单层依赖中,与God一样被显式地调用,这种工作方式被称为服务定位器(Service Locator)。Spring DI在多层依赖中,才体现为DI容器。
对于服务定位器或DI容器的划分,是按照一个工具所起的作用来区别。目前的God只是服务定位器,在下一节我们将God升级为DI容器;而Spring DI如同手机,在拍照时看作相机(服务定位器),通常作为手机(DI容器)。
下面先看看Spring DI如何完成依赖的注入。
【2017.12.30:
1.原博客 依赖注入(Dependency Injection)模式 大概的意思有,写得较垃圾:不流畅,例子不好。
2.不再将DI称为一种模式,而仅仅视为工具箱;强调 依赖注入(Dependency Injection)和框架、控制反转IoC,一点关系都没有。
3.例子 不再是A依赖2个具体类,而改成Demo→IMan<= Hubby→IWoman
4.伸手的方式,它不属于