从协作到合约 参考读物 关于依靠项插入的经典介绍,请参阅 Martin Fowler 的 “Inversion of Control Containers and the Dependency Injection Pattern”。关于使用 Spring 的依靠项插入的更多内容,请参阅 Professional java Development with the Spring Framework。这两者的链接都在 参考资料 中。 针对这篇文章的目的,可以把依靠项插入想像成对象和对象的执行环境之间的合约。对象(执行 ResourceConsumer、 Collaborator 和 ServiceClient 的其中一个角色或全部角色)同意不出去搜索自己需要的资源、它与之协作的合作伙伴或它使用的服务。相反,对象提供一种机制,让这些依靠项可以提供给它。接下来,执行环境同意在对象需要它的依靠项之前,向对象提供所有的依靠项。
解析依靠项的方法在不同的场景中各有不同。例如,在单元测试用例中,对象的执行环境是测试用例本身,所以测试设置代码有责任直接满足依靠项。在集成测试或应用程序在生产环境时,代理 负责寻找满足对象依靠项的资源,并把它们传递给对象。代理的角色通常是由轻量级容器扮演的,例如 Spring 框架。不管依靠项是如何解析的,被配置的对象通常不知道这类细节。在第二个示例中,它可能还不知道代理的存在。
代理(例如 Spring 框架)有四个要害职责,在整篇文章中我将不断提到这些职责,它们是:
确定对象需要配置(通常因为对象刚刚创建)
确定对象的依靠项
发现满足这些依靠项的对象
用对象的依靠项对它进行配置
从下面的各种依靠项插入解决方案可以看出,解决这些职责有多种策略。 使用 Spring 进行依靠项插入
在标准的 Spring 部署中,Spring 容器同时负责创建和配置核心应用程序对象(称为 bean)。因为容器既创建对象,又扮演代理的角色,所以对 Spring 容器来说,确定 bean 已经创建而且需要配置是件轻而易举的小事。通过查询应用程序的元模型,可以确定 bean 的依靠项,元模型通常是在 Spring 的配置文件中用 xml 表示的。
满足 bean 的依靠项的对象是容器治理的其他 bean。容器充当这些 bean 的仓库,所以可以用名称查询它们(或者在需要的时候创建)。最后,容器用新 bean 的依靠项对其进行配置。这通常是通过 setter 插入完成的(调用新 bean 的 setter 方法,把依靠项作为参数传递进去),虽然 Spring 支持其他形式的插入,例如构造函数插入和查询方法插入(请参阅 参考资料 学习关于使用 Spring 进行依靠项插入的更多内容。)