首页 > 学院 > 开发设计 > 正文

用AspectJ和Spring进行依赖项插入

2019-11-18 11:02:45
字体:
来源:转载
供稿:网友

  依靠项插入和面向方面编程是互补的技术,所以想把它们结合在一起使用是很自然的。请跟随 Adrian Colyer 一起探索两者之间的关系,并了解怎样才能把它们组合在一起,来促进高级的依靠项插入场景。

  依靠项插入和面向方面编程(AOP)是两个要害的技术,有助于在企业应用程序中简化和纯化域模型和应用程序分层。依靠项插入封装了资源和协调器发现的细节,而方面可以(在其他事情中)封装中间件服务调用的细节 —— 例如,提供事务和安全性治理。因为依靠项插入和 AOP 都会形成更简单、更轻易测试的基于对象的应用程序,所以想把它们结合在一起使用是很自然的。方面可以帮助把依靠项插入的能力带到更广的对象和服务中,而依靠项插入可以用来对方面本身进行配置。

  在这篇文章中,我将介绍如何把 SPRing 框架的依靠项插入与用 aspectJ 5 编写的方面有效地结合在一起。我假设您拥有基本的 AOP 知识(假如没有这方面知识 ,可以在 参考资料 中找到一些良好的起点),所以我的讨论将从对基于依靠项插入的解决方案中包含的要害角色和职责的分析开始。从这里,我将介绍如何通过依靠项插入配置单体(singleton)方面。因为配置非单体方面与配置域对象共享许多公共内容,所以后面我会研究一个应用于这两者的简单解决方案。总结这篇文章时,我会介绍如何为多个高级依靠项插入场景使用方面,其中包括基于接口的插入和重复插入。

  什么是依靠项插入?

  在 Domain-Driven Design 一书中,Eric Evans 讨论了如何把对象与建立对象的配置和关联的细节隐藏起来:

  对象的大部分威力在于对象内部复杂的配置和关联。应当对对象进行提炼,直到与对象的意义或者在交互中支持对象的作用无关的东西都不存在为止。这个中间循环的责任很多。假如让复杂对象负责自己的创建,就会出现问题。

  Evans 接着提供了一个汽车引擎的示例:它的众多部件一起协作,执行引擎的职责。虽然可以把引擎块想像成把一组活塞插入气缸,但是这样的设计会把引擎明显地弄复杂。相反,技工或机器人装配引擎,引擎本身只考虑自己的操作。

  虽然这个示例是我从书中介绍用于复杂对象创建的工厂 概念一节中取出的,但是我们也可以用这个概念解释依靠项插入技术的动机。

  从协作到合约
用AspectJ和Spring进行依靠项插入(图一)参考读物
关于依靠项插入的经典介绍,请参阅 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 进行依靠项插入的更多内容。)

  方面的依靠项插入

  像其他对象一样,方面可以从通过依靠项插入进行的配置中受益。在许多情况下,把方面实现为轻量级控制器 是良好的实践。在这种情况下,方面确定什么时候应当执行某些行为,但是会委托给协作器去执行实际的工作。例如,可以用异常处理策略对象配置异常处理方面。方面会探测出什么时候抛出了异常,并委托处理器对异常进行处理。清单 1 显示了基本的 RemoteException 处理方面:

清单 1. RemoteException 处理方面


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表