方面。从程序抽象的角度来说,可以对照OOP中的类来理解。OOP中的类(clas是实现世 界模板的一个抽象,其包括方法、属性、实现的接口、继承等。而AOP中的切面( aspect)是 实现世界领域问题的抽象,他除了包括属性、方法以外,同时切面中还包括切入点 Pointcut、 增强( advice等,另外切面中还可以给一个现存的类添加属性、构造函数,指定一个类实现 某一个接口、继承某一个类等。比如,在 Spring AOP中可以使用下面的配置来定义一个切 面: <aop: aspect id="aspect Demo ref="aspectBean"> <aop: pointcut id="some Pointcut" expression="execution(* Component. *(..)"7 <aop: after-returning pointcut -ref="log"method=""/ </aop: aspect> ■连接点 JOin point 连接点也就是运用程序执行过程中需要插入切面模块的某一点。连接点主要强调的 是一个具体的“点”概念。这个点可以是一个方法、一个属性、构造函数、类静态初始化块 甚至一条语句。比如前面的例子中,连接点就是指具体的某一个方法 在一般的AOP框架中,一般采用签名的方式来描述一个连接点,有的AOP框架只有很 少类型的连接点,如 Spring AOP中当前只有方法调用 ■切入点( Pointcuts) 切入点指一个或多个连接点,可以理解成一个点的集合。切入点的描述比较具体,而且 般会跟连接点上下文环境结合。比如,在前面的例子中,切入点“ execut lon( Component.*(.)”表示“在 Component类中所有以 business打头的方法执行过程 中”,其包含了3个连接点( business1、 business2、 business3)的集合。另外 “ Component类中的所有方法调用”、“包com. easyjf. servlce里面所有类中所有方 法抛出错误”、“类 UserInfo的所有 getter或 seater方法执行”,这些都可以作为 切入点。另外,在大多数AOP框架实现中,切入点还支持集合运算,可以把多个切入点通 过一定的组合,形成一个新的切入点。在 AspectJ中,可以使用|1、、!等操作符来组 合得到一个符合特定要求的切入点。如: pointcut setter( target(UserInfo)&&(call( void set*(String)ll call( void set*(int))) 表示所有 Userinfo类中的所有带一个 String或int型参数的 setter方法。 pointcut transaction(): target(service.)&&call(* save*(.)) 表示 servlce包中所有以save开头的方法 ■增强或通知( Advice Advice一词不管翻译成建议、通知或者增强,都不能直接反映其内容,因此本书主要 使用“增强”这一叫法。当然也可以把其仅看作是一个简单名词的来看待。增强( Advice)里 面定义了切面中的实际逻辑(即实现),比如日志的写入的实际代码,或是安全检查的实际 代码。换一种说法增强( Advice)是指在定义好的切入点处,所要执行的程序代码。比如,下 面的话都是用来描述增强( Advice)的例子:“当到达切入点 teeter时,检查该方法的参数是否 正确”、“在save方法出现错误这个切入点,执行一段错误处理及记录的操作”。一般情况下 增强(通知)主要有前増强、后增强、环绕増强三种基本类型。 前增强( before advice)一是指在连接点之前,先执行增强中的代码 后增加( after advice)一是指在连接点执行后,再执行增强中的代码。后增强一般分为
方面。从程序抽象的角度来说,可以对照 OOP 中的类来理解。OOP 中的类(class)是实现世 界模板的一个抽象,其包括方法、属性、实现的接口、继承等。而 AOP 中的切面(aspect)是 实现世界领域问题的抽象,他除了包括属性、方法以外,同时切面中还包括切入点 Pointcut、 增强(advice)等,另外切面中还可以给一个现存的类添加属性、构造函数,指定一个类实现 某一个接口、继承某一个类等。比如,在 Spring AOP 中可以使用下面的配置来定义一个切 面: <aop:aspect id="aspectDemo" ref="aspectBean"> <aop:pointcut id="somePointcut" expression="execution(* Component.*(..)" /> <aop:after-returning pointcut-ref="log" method="" /> </aop:aspect> 连接点(Join point) 连接点也就是运用程序执行过程中需要插入切面模块的某一点。连接点主要强调的 是一个具体的“点”概念。这个点可以是一个方法、一个属性、构造函数、类静态初始化块, 甚至一条语句。比如前面的例子中,连接点就是指具体的某一个方法。 在一般的 AOP 框架中,一般采用签名的方式来描述一个连接点,有的 AOP 框架只有很 少类型的连接点,如 Spring AOP 中当前只有方法调用。 切入点(Pointcuts) 切入点指一个或多个连接点,可以理解成一个点的集合。切入点的描述比较具体,而且 一般会跟连接点上下文环境结合。比如,在前面的例子中,切入点“execution(* Component.*(..)”表示“在 Component 类中所有以 business 打头的方法执行过程 中”,其包含了3个连接点(business1、business2、business3)的集合。另外, “Component 类中的所有方法调用”、“包 com.easyjf.service 里面所有类中所有方 法抛出错误”、“类 UserInfo 的所有 getter 或 seeter 方法执行”,这些都可以作为 切入点。另外,在大多数 AOP 框架实现中,切入点还支持集合运算,可以把多个切入点通 过一定的组合,形成一个新的切入点。在 AspectJ 中,可以使用||、&&、!等操作符来组 合得到一个符合特定要求的切入点。如: pointcut setter(): target(UserInfo) && (call(void set*(String)) || call(void set*(int))); 表示所有 UserInfo 类中的所有带一个 String 或 int 型参数的 setter 方法。 pointcut transaction():target(service..)&&call(* save*(..)) 表示 service 包中所有以 save 开头的方法。 增强或通知(Advice) Advice 一词不管翻译成建议、通知或者增强,都不能直接反映其内容,因此本书主要 使用“增强”这一叫法。当然也可以把其仅看作是一个简单名词的来看待。增强(Advice)里 面定义了切面中的实际逻辑(即实现),比如日志的写入的实际代码,或是安全检查的实际 代码。换一种说法增强(Advice)是指在定义好的切入点处,所要执行的程序代码。比如,下 面的话都是用来描述增强(Advice)的例子:“当到达切入点 seeter 时,检查该方法的参数是否 正确”、“在 save 方法出现错误这个切入点,执行一段错误处理及记录的操作”。一般情况下, 增强(通知)主要有前增强、后增强、环绕增强三种基本类型。 前增强(before advice)-是指在连接点之前,先执行增强中的代码。 后增加(after advice)-是指在连接点执行后,再执行增强中的代码。后增强一般分为 4
连接点正常返回增加及连接点异常返回增强等类型。 环绕增强( around advice)-是一种功能强大的增强,可以自由改变程序的流程,连接点 返回值等。在环绕增强中除了可以自由添加需要的横切功能以外,还需要负责主动调用连接 点(通过 procee执行激活连接点的程序。 ■引介( (ntroduction) 引介是指给一个现有类添加方法或字段属性,引介还可以在不改变现有类代码的情况 下,让现有的Java类实现新的接口,或者为其指定一个父类从而实现多重继承。相对于增 强( Advice)可以动态改变程序的功能或流程来说,引介( ntroduction)则用来改变一个类的静 态结构。比如我们可以让一个现有为实现 java. lang Cloneable接口,从而可以通过 cloned方 法复制这个类的实例 ■织入( weaving) 织入是指把解决橫切问题的切面模板,与系统中的其它核心模块通过一定策略或规则组 合到一起的过程。在java领域,主要包括以下三种织入方式 1、运行时织入一即在java运行的过程中,使用Java提供代理来实现织入。根据代理产 生方式的不同,运行时织入又可以进一步分为JSE动态代理及动态字节码生成两种方式 由于2SE动态代理只能代理接口,因此,需要借助于一些动态字节码生成器来实现对类的 动态代理。大多数AOP实现都是采用这种运行时织入的方式 2、类加载器织入一指通过自定义的类加载器,在虚拟机JVM加载字节码的时候进行织 入,比如 Aspect Werkz(已并入 Aspec)及 JBoss就使用这种方式。 3、编译器织入一使用专门的编译器来编译包括切面模块在内的整个应用程序,在编译 的过程中实现织入,这种织入是功能最强大的。编译器织入的AOP实现一般都是基于语言 扩展的方式,即通过对标准java语言进行一些简单的扩展,加入一些专用于处理AOP模块 的关键字,定义一套语言规范,通过这套语言规范来开发切面模块,使用自己的编译器来生 成java字节码。 AspectJ主要就是是使用这种织入方式 ■拦截器( interceptor) 拦截器是用来实现对连接点进行拦截,从而在连接点前或后加入自定义的切面模块功 能。在大多数JAVA的AOP框架实现中,都是使用拦截器来实现字段访问及方法调用的拦 截( interception)。所用作用于同一个连接点的多个拦截器组成一个连接器链( Interceptor chain),链接上的每个拦截器通常会调用下一个拦截器。 Spring AOP及 JBOOs AOP实现都是 采用拦截器来实现的。 ■目标对象( Target object 指在基于拦截器机制实现的AOP框架中,位于拦截器链上最未端的对象实例。一般情 况下,拦截器未端都包含一个目标对象,通常也就是实际业务对象。当然,也可以不使用目 标对象,直接把多个切面模块组织到一起,形成一个完整最终应用程序,整个系统完全使用 基于AOP编程方法实现,这种情况少见。 AOP代理( proxy) Aop代理是指在基于拦截器机制实现的AOP框架中,实际业务对象的代理对象。这个 代理对象一般被切面模块引用,AOP的切面逻辑正是插入在代理对象中来执行的。AOP代 理的包括J2SE的代理以及其它字节码生成工具生成的代理两种类型
连接点正常返回增加及连接点异常返回增强等类型。 环绕增强(around advice)-是一种功能强大的增强,可以自由改变程序的流程,连接点 返回值等。在环绕增强中除了可以自由添加需要的横切功能以外,还需要负责主动调用连接 点(通过 proceed)来执行激活连接点的程序。 引介(Introduction) 引介是指给一个现有类添加方法或字段属性,引介还可以在不改变现有类代码的情况 下,让现有的 Java 类实现新的接口,或者为其指定一个父类从而实现多重继承。相对于增 强(Advice)可以动态改变程序的功能或流程来说,引介(Introduction)则用来改变一个类的静 态结构。比如我们可以让一个现有为实现 java.lang.Cloneable 接口,从而可以通过 clone()方 法复制这个类的实例。 织入(weaving) 织入是指把解决横切问题的切面模板,与系统中的其它核心模块通过一定策略或规则组 合到一起的过程。在 java 领域,主要包括以下三种织入方式: 1、运行时织入-即在 java 运行的过程中,使用 Java 提供代理来实现织入。根据代理产 生方式的不同,运行时织入又可以进一步分为 J2SE 动态代理及动态字节码生成两种方式。 由于 J2SE 动态代理只能代理接口,因此,需要借助于一些动态字节码生成器来实现对类的 动态代理。大多数 AOP 实现都是采用这种运行时织入的方式。 2、类加载器织入-指通过自定义的类加载器,在虚拟机 JVM 加载字节码的时候进行织 入,比如 AspectWerkz(已并入 AspecJ)及 JBoss 就使用这种方式。 3、编译器织入-使用专门的编译器来编译包括切面模块在内的整个应用程序,在编译 的过程中实现织入,这种织入是功能最强大的。编译器织入的 AOP 实现一般都是基于语言 扩展的方式,即通过对标准 java 语言进行一些简单的扩展,加入一些专用于处理 AOP 模块 的关键字,定义一套语言规范,通过这套语言规范来开发切面模块,使用自己的编译器来生 成 java 字节码。AspectJ 主要就是是使用这种织入方式。 拦截器(interceptor) 拦截器是用来实现对连接点进行拦截,从而在连接点前或后加入自定义的切面模块功 能。在大多数 JAVA 的 AOP 框架实现中,都是使用拦截器来实现字段访问及方法调用的拦 截(interception)。所用作用于同一个连接点的多个拦截器组成一个连接器链(interceptor chain),链接上的每个拦截器通常会调用下一个拦截器。Spring AOP 及 JBoos AOP 实现都是 采用拦截器来实现的。 目标对象(Target object) 指在基于拦截器机制实现的 AOP 框架中,位于拦截器链上最未端的对象实例。一般情 况下,拦截器未端都包含一个目标对象,通常也就是实际业务对象。当然,也可以不使用目 标对象,直接把多个切面模块组织到一起,形成一个完整最终应用程序,整个系统完全使用 基于 AOP 编程方法实现,这种情况少见。 AOP 代理(proxy) Aop 代理是指在基于拦截器机制实现的 AOP 框架中,实际业务对象的代理对象。这个 代理对象一般被切面模块引用,AOP 的切面逻辑正是插入在代理对象中来执行的。AOP 代 理的包括 J2SE 的代理以及其它字节码生成工具生成的代理两种类型。 5
513AOP与OOP关系 在面向对象(OOP)的编程中,我们是通过对现实世界的抽象及模型化上来分析问题,也 即把一个大的应用系统分成一个一个的对象,然后把他们有机的组合在一起完成;而在面向 切面(AOP)舶的编程中,分析问题是从关注点的角度出发,把一个软件分成不同的关注点,软 件核心业务逻辑一般都比较集中、单一,这种关注点称为核心关注点,而一些关注属于分散 在软件的各个部分(主要是软件核心业务逻辑),这种关注点称为横切关注点。核心关注点可 以通过传统的OOP方法来实现,而横切关注点则可以通过AOP的方法解决,即把实现相同 功能、解决共性问题并分散在系统中各个部分的模块纳入一个切面中来处理。使用AOP编 程,除了把一些具有共性的功能放到切面模块中以外,还可以在切面中给已有的类增加新的 属性、实现新的接口等。也就是说,不但可以从类的外部动态改变程序的运行流程、给程序 增加特定功能,还可以改变其静态结构 因此,面向对象编程(OOP)解决问题的重点在于对具体领域模型的抽象,而面向切面 编程(AOP)解决问题的关键则在于对关注点的抽象。也就是说,系统中对于一些需要分散 在多个不相关的模块中解决的共同问题,则交由AOP来解决;AOP能够使用一种更好的方 式来解决OOP不能很好解决的横切关注点问题以及相关的设计难题来实现松散耦合。因此, 面向方面编程(AOP)提供另外一种关于程序结构的思维完善了OOP,是OOP的一种扩展 技术,弥补补了OOP的不足。 OOP编程基本流程 1、归纳分析系统,抽象领域模型 2、使用 class来封装领域模型,实现类的功能; 3、把各个相关联的类组装到一起形成一个完整的系统。 AOP编程基本流程 1、归纳分析系统中的关注点,分解切面; 2、按模块化的方式实现各个关注点中的功能,使用传统的编程方法如OOP; 3、按一定的规则分解及组合切面(织入或集成),形成一个完整的系统 514AOP联盟简介 AOP联盟( AOP Alliance)是由Java领域比较知名的一些专家及组织为了推进AOP运用 研究,建立一个通用的AOP规范而成立起来的组织。组织中的成员都是在AOP编程思想及 技术研究中有着比较突出贡献的专家及学者,其中有 AspectWerkz的 Jonas boner、JAC的 Laurent Martelli, Spring的发起人 Rod Jonhson等等 通过AOP联盟的共同研究,可以避免一些重复性工作。AOP联盟提供了一个公共的 AOP API,大多数知名的AOP框架或实现(如 JBoss Aop、 AspectJ、 Spring等)都直接或间 接对其AOP进行了集成或支持。从而可以供各种AOP开发工具及框架能简单在各个AOP 应用环境中应用、移植 AOP联盟API简介 AOP联盟制订了一套用于规范AOP实现的底层API,通过这些统一的底层AP,可以 使得各个AOP实现及工具产品之间实现相互移植。这些API主要以标准接口的形式提供 是AOP编程所要解决的横切交叉关注点问题各部件的最高抽象, Spring的AOP框架中也直 接以这些API为基础所构建。下面我我们来看看当前AOP联盟发布的AOP相关接口。 AOP联盟的AP主要包括四个部分,第一个是aop包,定义了一个表示增强( Advice
5.1.3 AOP 与 OOP 关系 在面向对象(OOP)的编程中,我们是通过对现实世界的抽象及模型化上来分析问题,也 即把一个大的应用系统分成一个一个的对象,然后把他们有机的组合在一起完成;而在面向 切面(AOP)的编程中,分析问题是从关注点的角度出发,把一个软件分成不同的关注点,软 件核心业务逻辑一般都比较集中、单一,这种关注点称为核心关注点,而一些关注属于分散 在软件的各个部分(主要是软件核心业务逻辑),这种关注点称为横切关注点。核心关注点可 以通过传统的 OOP 方法来实现,而横切关注点则可以通过 AOP 的方法解决,即把实现相同 功能、解决共性问题并分散在系统中各个部分的模块纳入一个切面中来处理。使用 AOP 编 程,除了把一些具有共性的功能放到切面模块中以外,还可以在切面中给已有的类增加新的 属性、实现新的接口等。也就是说,不但可以从类的外部动态改变程序的运行流程、给程序 增加特定功能,还可以改变其静态结构。 因此,面向对象编程(OOP)解决问题的重点在于对具体领域模型的抽象,而面向切面 编程(AOP)解决问题的关键则在于对关注点的抽象。也就是说,系统中对于一些需要分散 在多个不相关的模块中解决的共同问题,则交由 AOP 来解决;AOP 能够使用一种更好的方 式来解决 OOP 不能很好解决的横切关注点问题以及相关的设计难题来实现松散耦合。因此, 面向方面编程 (AOP) 提供另外一种关于程序结构的思维完善了 OOP,是 OOP 的一种扩展 技术,弥补补了 OOP 的不足。 OOP 编程基本流程 1、 归纳分析系统,抽象领域模型; 2、 使用 class 来封装领域模型,实现类的功能; 3、 把各个相关联的类组装到一起形成一个完整的系统。 AOP 编程基本流程 1、归纳分析系统中的关注点,分解切面; 2、按模块化的方式实现各个关注点中的功能,使用传统的编程方法如 OOP; 3、按一定的规则分解及组合切面(织入或集成),形成一个完整的系统。 5.1.4 AOP 联盟简介 AOP 联盟(AOP Alliance)是由 Java 领域比较知名的一些专家及组织为了推进 AOP 运用 研究,建立一个通用的 AOP 规范而成立起来的组织。组织中的成员都是在 AOP 编程思想及 技术研究中有着比较突出贡献的专家及学者,其中有 AspectWerkz 的 Jonas Bonér、JAC 的 Laurent Martelli、Spring 的发起人 Rod Jonhson 等等。 通过 AOP 联盟的共同研究,可以避免一些重复性工作。AOP 联盟提供了一个公共的 AOP API,大多数知名的 AOP 框架或实现 (如 JBoss AOP、AspectJ、Spring 等)都直接或间 接对其 AOP 进行了集成或支持。从而可以供各种 AOP 开发工具及框架能简单在各个 AOP 应用环境中应用、移植。 AOP 联盟 API 简介 AOP 联盟制订了一套用于规范 AOP 实现的底层 API,通过这些统一的底层 API,可以 使得各个 AOP 实现及工具产品之间实现相互移植。这些 API 主要以标准接口的形式提供, 是 AOP 编程所要解决的横切交叉关注点问题各部件的最高抽象,Spring 的 AOP 框架中也直 接以这些 API 为基础所构建。下面我我们来看看当前 AOP 联盟发布的 AOP 相关接口。 AOP 联盟的 API 主要包括四个部分,第一个是 aop 包,定义了一个表示增强(Advice) 6
的标识接口,各种各样的增强( Advice)都继承或实现了这个接口;aop包中还包括了一个用 于描述AOP系统框架错误的运行时异常 AspectEκ ception 第二个部分是 Intercept包,也就是拦截器包,这个包中规范了AOP核心概念中的 连接点( Join point)及增强( Advice)类型 第三部及第四部分是 Instrument及ref1ect包。这两个包中的API主要包括AOP 框架或产品为了实现把横切关注点的模块与核心应用模块组合集成,所需要使用的设施、技 术及底层实现规范等 “图5-1”及“图5-2”是两张关于介绍AOP联盟所发布的连接点( Joinpint)及增 强( Advice)的UML结构图,通过这两张图,我们可以更加清晰了解一些AoP框架(如 Spring中的AOP框架)的体系结构 <<Interface>> Join point ● getThisO: bject o getstaticParto): Aaces sibleobjecl △ I<<Interface>> FieldAccess Invocation o getFieldo: Field getArgumertsO: Object] o getValue ToSet(): Cbject o getAccess Type: int Const ric torlnvoc ation Metho iNvocation o getconstruxtort: Construc ar ● getMethodo: Method 图5-1AOP联盟定义的连接点( join point)API I <<Interface>> Advice <<Interface>> o construc(n invocation Constructor Invocation) Cbject FieldIntercepto o get(in Field ead: FieldAccess ): Cbject
的标识接口,各种各样的增强(Advice)都继承或实现了这个接口;aop 包中还包括了一个用 于描述 AOP 系统框架错误的运行时异常 AspectException。 第二个部分是 intercept 包,也就是拦截器包,这个包中规范了 AOP 核心概念中的 连接点(join point)及增强(Advice)类型。 第三部及第四部分是 instrument 及 reflect 包。这两个包中的 API 主要包括 AOP 框架或产品为了实现把横切关注点的模块与核心应用模块组合集成,所需要使用的设施、技 术及底层实现规范等。 “图 5-1”及“图 5-2”是两张关于介绍 AOP 联盟所发布的连接点(Joinpint)及增 强(Advice)的 UML 结构图,通过这两张图,我们可以更加清晰了解一些 AOP 框架(如 Spring 中的 AOP 框架)的体系结构。 图 5-1 AOP 联盟定义的连接点(join point)API 7
图5-2AOP联盟定义的增强( Advice)APl 515AOP相关框架及工具简介 一个AOP框架或实现主要有两部分功能,第一部分是通过定义一种机制来实现连接点、 切入点及切面定义(描述)及封装实现,可以是一套语言规范或编程规范:另外一个部分就是 提供把切面模块的逻辑通过织入( weaving),与系统的其它部分组合到一起,形成一个完整 的系统。要使用AOP技术,不需要从最底层开始逐一实现,可以使用一些现存的AOP框架 或辅助工具来引入AOP编程方法的支持,下面我们简单介绍Java中的一些AOP框架及工 具。 主要的AOP实现及框架 Aspect小:对java进行了扩展,形成一个功能强大、灵活、实用的AOP语言。 Aspect. 在java的基础上,加入一些AOP相关的关键字、语法结构形成一门AOP语言,其编译出 来的程序是普通的Java字节码,因此,可以运行于任何Java平台, AspectJ被誉为AOP领 域的急先锋。 AspectWerkz:一个动态、轻量级、性能表现良好的AOP框架。可能通过使用配置文件、 配合其提供的类加载器实现动态织入。该框架的当前已经与 AspectJ合并, AspectJ5就合 并后的成果。 JBoss--AOP: BOos公司开发的基于方法拦截及源码级数据的AOP实现框架,最开始 属于 BOos服务器的一部分,可以脱离Joos单独作为一个AOP框架使用。 Spring-AOP: Spring框架中也提供了一个AOP实现,使用基于代理及拦截器的机制 与 Spring IOC容器融入一体的AOP框架。 Spring AOP采用运行时织入方式,使得可以在基 于 Spring框架的应用程序中使用各种声明式系统级服务 AOP相关的框架或工具 除了上面介绍的几个AOP实现及框架以外,在Java领域,也有很多成熟的AOP相关 技术,提供动态代理、拦截器、动态字节码生成及转换工具。下面简单列举一些用得比较多 的 ASM:一个轻量级的字节码生成及转换器。 BCEL:一个实用的字节码转换工具,在JAC中就是通过BCEL来实现方法拦截机制 CGLIB:一个功能强大的动态代理代码工具,可以根据指定的类动态生成一个子类 并提供了方法拦截的相关机制,并且在大量的流行开源框架(如 Hibernate、 Spring等)中得到 使用 Javassist: JBoss提供的java字节码转换器,在 BOos的很多项目中使用,包括 JBoss AOP 516AOP在企业级应用程序中的作用 在企业级的应用程序中,有很多系统级服务都是横切性质的,比如事务处理、安全、对 象池及缓存管理等。在以EJB为代表的重量级J2EE企业级应用中,这些系统级服务由EJB 容器(即J2EE应用服务器)提供,Bean的使用者可以通过EB描述文件及服务器提供商的特 定配置文件,声明式的使用这些系统服务 而对于轻量级的应用中,由于业务组件都是多数是普通的POJO,要使用这种声明式的
图 5-2 AOP 联盟定义的增强(Advice) API 5.1.5 AOP 相关框架及工具简介 一个 AOP 框架或实现主要有两部分功能,第一部分是通过定义一种机制来实现连接点、 切入点及切面定义(描述)及封装实现,可以是一套语言规范或编程规范;另外一个部分就是 提供把切面模块的逻辑通过织入(weaving),与系统的其它部分组合到一起,形成一个完整 的系统。要使用 AOP 技术,不需要从最底层开始逐一实现,可以使用一些现存的 AOP 框架 或辅助工具来引入 AOP 编程方法的支持,下面我们简单介绍 Java 中的一些 AOP 框架及工 具。 主要的 AOP 实现及框架 AspectJ: 对 java 进行了扩展,形成一个功能强大、灵活、实用的 AOP 语言。AspectJ 在 java 的基础上,加入一些 AOP 相关的关键字、语法结构形成一门 AOP 语言,其编译出 来的程序是普通的 Java 字节码,因此,可以运行于任何 Java 平台,AspectJ 被誉为 AOP 领 域的急先锋。 AspectWerkz:一个动态、轻量级、性能表现良好的 AOP 框架。可能通过使用配置文件、 配合其提供的类加载器实现动态织入。该框架的当前已经与 AspectJ 合并,AspectJ5 就 合 并后的成果。 JBoss-AOP:JBoos 公司开发的基于方法拦截及源码级数据的 AOP 实现框架,最开始 属于 JBoos 服务器的一部分,可以脱离 JBoos 单独作为一个 AOP 框架使用。 Spring-AOP:Spring 框架中也提供了一个 AOP 实现,使用基于代理及拦截器的机制, 与 Spring IOC 容器融入一体的 AOP 框架。Spring AOP 采用运行时织入方式,使得可以在基 于 Spring 框架的应用程序中使用各种声明式系统级服务。 AOP 相关的框架或工具 除了上面介绍的几个 AOP 实现及框架以外,在 Java 领域,也有很多成熟的 AOP 相关 技术,提供动态代理、拦截器、动态字节码生成及转换工具。下面简单列举一些用得比较多 的: ASM:一个轻量级的字节码生成及转换器。 BCEL:一个实用的字节码转换工具,在 JAC 中就是通过 BCEL 来实现方法拦截机制。 CGLIB:一个功能强大的动态代理代码工具,可以根据指定的类动态生成一个子类, 并提供了方法拦截的相关机制,并且在大量的流行开源框架(如 Hibernate、Spring 等)中得到 使用。 Javassist: JBoss 提供的 java 字节码转换器,在 JBoos 的很多项目中使用,包括 JBoss AOP。 5.1.6 AOP 在企业级应用程序中的作用 在企业级的应用程序中,有很多系统级服务都是横切性质的,比如事务处理、安全、对 象池及缓存管理等。在以 EJB 为代表的重量级 J2EE 企业级应用中,这些系统级服务由 EJB 容器(即 J2EE 应用服务器)提供,Bean 的使用者可以通过 EJB 描述文件及服务器提供商的特 定配置文件,声明式的使用这些系统服务。 而对于轻量级的应用中,由于业务组件都是多数是普通的 POJO,要使用这种声明式的 8