Welcome 微信登录

首页 / 软件开发 / JAVA / 用AspectJ构造方面库

用AspectJ构造方面库2011-05-15 IBM 春郭迎 志甘 鹏刘昕1.方面库

大家都知道,各种AOP工具的核心就是切入点(pointcut)和通知(advice) 的声明。切入点描述了主程序执行与方面执行相遇的地方,也就是被横切的位置 ;通知则描述了在程序执行过程中遇到匹配的切入点时应当采取什么行动。假设 已经开发了一个方面,并且感觉它适用于其他项目,那么可以泛化这个方面,并 把它隔离到自己独立的项目中,形成一个库,即方面库(Aspect Library)。方 面库提供了某个功能的内部执行逻辑和基础设施,通过切入点的实例化将方面库 与某个特定项目连接起来。例如提供应用程序性能监视的方面库,实现了所有性 能监视相关的方法和通知,某应用程序使用该库的时候,只需要把库的切入点定 义为应用特定的连接点即可,而无需关心性能监视功能的具体实现。这就是方面 库的基本概念。

方面库是AOP工具具有扩展性的体现,目前常用的AOP工具,如JBoss AOP、 Spring AOP、AspectJ等,都有对方面库的支持,但由于它们实现AOP的方法不同 ,方面库的定义和使用方法也不相同。在JBoss AOP和Spring AOP中,通知的实现 都是通过普通Java语法定义,切入点到通知的绑定是通过显式的XML文档或者注释 实现的。所以将方面库应用于应用程序就可以很容易地通过在 XML 中或通过注释 定义新的通知绑定而实现。并且JBoss和Spring系统本身已经提供了很好的方面库 供用户使用。

AspectJ是Java 语言语法和语义的扩展,它提供了自己的一套处理方面的关键 字,这些都决定了用AspectJ构造方面库的方法具有一定的特殊性。所以AspectJ 构造的方面库一直不象JBoss AOP和Spring AOP那样普遍,AspectJ也并没有提供 任何方面库。令人欣慰的是, AspectJ从AspectJ5版本开始提供对注释的支持, 它的编辑工具AJDT中逐渐加入了对方面库的支持功能,从而使得使用AspectJ构造 方面库变得越来越容易。本文就来介绍如何用AspectJ构造方面库。

2.AspectJ对方面库的技术支持

方面库的实现在于切入点的实例化方式。AspectJ对切入点定义方法的支持导 致了两种完全不同的方面库实现方法--使用抽象方面(abstract aspect)的方法 和使用注释的方法。本章将详细介绍这两种方式。

AspectJ是Java语言的扩展。方面在AspectJ语言中用aspect关键字标示,它类 似于Java类,可以定义成抽象的,也存在继承关系。切入点在AspectJ语言中用关 键字pointcut标示,它有一套完整的语法来描述切入点,也可以定义成抽象的, 即没有实际定义的切入点。抽象 pointcut只能定义在抽象方面中。如清单 1所示 ,抽象方面A里面定义了一个抽象pointcut名叫publicCall。抽象方面如同抽象类 一样,可以被继承,继承抽象方面的方面必须重载抽象 pointcut,即赋予抽象 pointcut实际的定义。如清单 2所示,方面B继承了抽象方面A,重载了名叫 publicCall的pointcut,给它一个具体的定义。

清单 1 抽象方面

public abstract aspect A {
abstract pointcut publicCall(int i);
}

清单 2 继承抽象方面的子方面

public aspect B extends A {
pointcut publicCall(int i): call(public Foo.m(int)) && args(i);
}

AspectJ对继承和抽象的支持正是我们构造方面库的基础。抽象方面包含抽象 的切入点和具体的通知,正符合方面库的特征,可以使用抽象方面来构造方面库 文件。继承抽象方面的子方面必须具体化切入点,可以把它当作方面库在具体应 用程序中的实施。为了加深理解,我们将在接下来的章节中使用抽象方面技术制 作一个简单的记录踪迹的方面库,并扩展它以应用到具体项目中。

从AspectJ 5开始支持的注释是另外一种构造方面库的技术基础。Java5引入了 注释这种类型,它以注释的形式来表达程序中各成员的元数据信息,采用符号@标 示。 Java5中可以被注释修饰的Java程序成员有很多,AspectJ 5能支持的注释包 括修饰方面、方法、属性、构造函数和通知,修饰方法和通知的参数的注释也能 支持,但是不支持pointcut和declare语句上的注释。为了支持注释类型, AspectJ 5扩展了pointcut语法,可以匹配存在或者不存在的注释类型。例如清单 3中的名叫onewayMethod的pointcut可以匹配所有被注释@Oneway修饰的方法调用 。

清单 3 含有注释的pointcut

public aspect C {
pointcut onewayMethod: call(@Oneway * *(..));
}

AspectJ 5对注释的支持简化了实施库的方法,我们可以很容易地想到,在把 方面库实施到应用程序时,可以利用注释标明具体的切入点的位置。在构造方面 库文件时,只需要定义好与注释相关的切入点,并规定该切入点上的具体的通知 内容就可以了。我们同样会在下面的章节中介绍使用注释制作简单的方面库的过 程。