概述
面向方面的程序设计(AOP)是一个激动人心的新规范,和已经有十几年历史的面向对象的程序设计(OOP)在软件开发上有相同的作用。 AOP和OOP不是相互竞争的技术,实际上它们相辅相成的十分融洽。面向对象的程序设计对于建模常见的对象等级体系非常有用。 它的不足之处在于处理跨多个非关联对象模型的常见情况;这时就有AOP的用武之地了。AOP允许你跨关联,使用单独的、彼此之间非常不同的对象模型。 它允许你层次化--而不是嵌入--函数,以便代码更易读、更便于维护。 我们喜欢把面向对象的程序设计想象成为自顶向下的软件开发,而面向方面的程序设计则是自左向右;它们是完全正交的技术,彼此之间相辅相成的十分融洽。
面向对象的程序设计的手段是继承、封装和多态性,而面向方面的程序设计的组件是通知/监听器(advice/interceptor)、引入(introduction)、元数据(metadata)和切入点(pointcut) 。 让我们看看这些定义。
通知/监听器(advice/interceptor)
一个通知是被某一事件触发的程序逻辑。 它是可以被插入一个方法调用者和实际的方法之间的行为。 通知实际上是面向方面的程序设计的关键。这些构造允许你定义横切(cross-cutting)行为。通知允许你透明地应用象记录和度量这样的事到现有的对象模型中。
在JBoss AOP中,我们使用监听器实现通知。你可以定义监听器监听方法调用、构造器调用和字段访问。稍后,我们将研究如何应用这些监听器到一个现有的对象模型中。
引入
引入是一种添加方法或者字段到一个现有类的方法。它们甚至允许你改变一个现有类目前实现的接口并且引入一个混合类实现这些新接口。
引入允许你把多继承带到简单的Java类中。引入的一个重要的使用实例就是你有一个想有运行时间接口的方面。你想跨不同的对象层次应用你的方面,但是你仍然想应用程序开发者能够调用指定方面API。
Apple apple = new Apple();
LoggingAPI logging = (LoggingAPI)apple;
Apple.setLoggingLevel(VERBOSE);
引入可以是一个把新API附加于一个现有对象模型的方法。
元数据
元数据是可以附属于一个类的附加信息,或者以静态方式或者在运行时间。当你可以动态地把元数据附上到一个对象给定的实例中的时候,它将更加有效。当你正在编写可用于任何对象的一般的方面的时候,元数据显得特别重要,但是程序逻辑必须知道指定类的信息。元数据被使用的一种很类似的情况是EJB规范。在EJB XML配置描述符中,你在一个每方法的基础上定义事务属性。应用程序服务器知道何时何地开始、暂停或者委托一个事务,因为你已经定义Required、RequiresNew、Supports等方法。在你的EJB类和事务管理程序绑定的元数据里,是bean的XML配置文件。
C#已经把元数据构建入语言中。XDoclet是另一个正在工作的很好的元数据的例子。如果你曾经用过XDoclet来生成EJB文件和配置描述符,你肯定知道元数据强大的功能。Java Community Process(JCP)达成协议,元数据被添加进JDK 1.5 (见JSR175)。直到JSR 175真正成为一种规范,一个好的AOP框架才能提供一个机制,声明在运行时间有效的类级元数据。
切入点
如果监听器,引入和元数据是面向方面的程序设计的特性,那么切入点就是把这些特性联系起来的纽带。切入点告诉面向方面的程序设计框架,哪个监听器将和哪个类捆绑在一起,哪些元数据将用于哪些类,或者引入将被导入到哪些类中。 切入点定义能够用于你的应用程序的类的各种面向方面的程序设计特性。