面向切面编程 Aspect Oriented Programming
本译文同步发表在译言“软件设计与开发”小组(http://www.yeeyan.com/groups/show/3056)。“软件设计与开发”小组关注软件设计思想,软件开发模式等最新前沿文章的翻译,有兴趣的请加入。
原文出处:http://www.developer.com/design/article.php/3308941
作者:Yasser EL-Manzalawy
面向切面编程(AOP)被认为是一项有前途的新技术,它通过对交叉业务的分隔来实现,而这在面向对象编程里很难做到。本文通过一个新的范例介绍AOP的基本概念。
面向对象编程 Object Oriented Programming
今天,面向对象编程已经成为主流的编程模式,在这里,现实问题被分解为一个个的包含数据和行为的对象。
OOP通过设计和语言本身提供的模块化、封装、继承、多态来实现软件复用。尽管OOP在建模以及实现复杂软件方面非常成功,它仍然有一些问题。在大型工程实践中,程序员发现在模块中越来越难以分离交叉业务,他们的代码也变得更加难维护。对程序设计的一丝改动都会引发大量不相关模块的改动。
交叉业务 Crosscutting Concerns
一个交叉业务的例子是“日志”,日志在分布式系统中经常被用来记录方法调用,以辅助调试。假设我们在每个函数开始前和结束后都写日志,这会使我们对所有包含方法的类做“横切”(crosscutting)。其他典型的交叉业务包括:上下文敏感的错误处理,性能优化,以及设计模式。
交叉业务可能出现在某些程序中,尤其是那些大型程序中。然而另一方面,对系统的重新设计可以将交叉业务转换成对象。AOP假定交叉业务会出现在程序中,并无法从重构中被剔除出去。
面向切面编程 Aspect Oriented Programming
AOP是一项新的技术,它将交叉业务分离出来,作为独立单元——切面——处理。切面即是交叉业务的模块化实现,它封装了对各个类都有影响的行为,作为新的可重用的模块。利用AOP,我们可以用OO编程语言(如Java)开始项目,然后我们单独使用切面处理交叉业务。最后,代码和切面一起通过编织器(aspect weaver)组织成最终可执行文件。图1说明了"编织器"工作过程。注意,原始的代码不需要知道切面的任何功能;只要除去切面代码并重新编译,就能得到初始代码的功能。
Figure 1: Aspect Weaver
AOP以这种方式加强了OO编程,而并非取代它。它将广泛被关注的交叉业务以模块方式组织为另外单元,这些单元被称为切面,因此叫它面向切面编程。
面向切面编程和Java
AOP是一种编程概念,因此它并未绑定到任何特定的语言。事实上,它对所有单独的、垂直分解式(译注:AOP通常被认为是横向分解)的语言(不仅是OO语言)都有帮助。AOP在不同语言都有实现(如 C++, Smalltalk, C#, C, Java).
当然,受益最大的还是Java语言。下面是一些支持Java AOP的工具:
由Xerox PARC所创建的AspectJ被认为是Java语言在AOP方面的一个扩展。本文下面部分主要涉及AspectJ.
连接点,切入点,通知和引入 Join points, Pointcut, Advice, and Introduction
就如OOP的概念包含继承、封装、多态一样,组成AOP的概念是连接点,切入点,通知和引入(Join points, Pointcut, Advice, and Introduction)。为更好的理解这些术语,我们看一下下面的例子。
public class TestClass {
public void sayHello () {
System.out.println ("Hello, AOP");
}
public void sayAnyThing (String s) {
System.out.println (s);
}
public static void main (String[] args) {
sayHello ();
sayAnyThing ("ok");
}
}
Listing 1: TestClass.java
我们的Java代码保存在TestClass.java,假设我们想用切面做如下修改:
- 在对TestClass.sayHello()方法调用之前和之后,都打印一行信息
- 检查TestClass.sayAnyThing() 方法的参数,至少3个字符才能执行
下面就是AspectJ 的实现。
1: public aspect MyAspect {
2: public pointcut sayMethodCall (): call (public void
TestClass.say*() );
3: public pointcut sayMethodCallArg (String str): call
(public void TestClass.sayAnyThing (String))
&& args(str);
4: before(): sayMethodCall() {
5: System.out.println("\n TestClass." +
thisJoinPointStaticPart.getSignature().getName() +
"start..." );
6: }
7: after(): sayMethodCall() {
8: System.out.println("\n TestClass." +
thisJoinPointStaticPart.getSignature().getName() +
" end...");
9: }
10: before(String str): sayMethodCallArg(str) {
11: if (str .length() < 3) {
12: System.out.println ("Error: I can't say words less than 3
characters");
13: return;
14: }
15: }
16: }
Listing 2: MyAspect.aj
Line 1 定义了一个aspect,就像我们定义Java 类。跟任何Java类一样,aspect也可以拥有成员变量和方法,另外它还可以包含切入点(pointcuts),通知(advices)和引入(introductions).
Lines 2和Line 3指定我们的修改在TestClass什么地方起作用。按AspectJ术语,我们定义了2个切入点(pointcuts)。为了弄清楚切入点(pointcut)是什么意思,我们需要先定义连接点(join points).
连接点(join points)表示在程序执行过程中预先定义的“点”,AspectJ 中典型的连接点包括:方法或构造器的调用,方法或构造器的执行,字段的读取,异常处理,以及静态或动态的初始化。本文例子中,我们定义了2处连接点:对TestClass.sayHello方法的调用及对TestClass.sayAnyThing方法的调用。
切入点(Pointcut)是符合预定义规范的连接点(a set of join points)的集合,这是一个语言上的构造概念。 规范可以是明确的的函数名,也可以是包含通配符的函数名。
public pointcut sayMethodCall (): call (public void
TestClass.say*() );
上面一行,我们定义了一个切入点(pointcut),叫做 sayMethodCall,它会检查所有对TestClass.sayHello方法的调用。另外,它同样会检查TestClass 类里所有以"say"开头,参数为空的公共方法(举个例子:TestClass.sayBye).
切入点(Pointcuts)用来定义“通知” (advice). AspectJ 的advice用来定义在连接点执行之前、之中、之后的额外代码。在我们的例子中,line 4-6 和line7-9 分别定义了对第一个切入点执行之前和之后的通知。Lines10-15定义了对第二个切入点的通知,即设置TestClass.sayAnyThing 方法执行的一个前置条件。
切入点pointcuts和通知advice能让你影响程序的动态执行部分,与此不同,引入(introduction)允许切面修改程序中静态的部分。通过引入(introduction), 切面可以为类添加新的方法及变量,声明类实现的接口,或将捕获的异常转为未捕获的异常。 Introduction和一个更为实用的AOP的例子是我未来一篇文章的主题。
AspectJ 编译器
回到开头,你需要从AspectJ 的官方网站上下载它的最新版本并安装它(免费的),编译和运行我们的例子非常简单:
ajc MyAspect.aj TestClass.java
java TestClass
值得注意的是,Java源代码TestClass.java 没有任何改动。你只要使用Java编译器重新编译它就能得到最初的原始程序功能。
分享到:
相关推荐
面向切面编程(Aspect-Oriented Programming,简称 AOP)是一种编程范式,它通过将横切关注点(cross-cutting concerns)从业务逻辑中分离出来,并将其封装为独立的组件,来降低软件系统的耦合度。AOP 的核心思想是...
面向切面编程(AOP)是一种编程范式,它旨在将关注点分离,使得系统中的核心业务逻辑与系统服务(如日志、事务管理、权限控制等)可以解耦。在Android开发中,AOP的应用可以帮助我们更好地组织代码,提高可维护性和...
面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,旨在将关注点分离,使得业务逻辑和系统服务(如日志、事务管理、权限控制等)能够解耦。这种编程方式允许程序员定义“切面”,这些切面封装了特定...
面向切面编程(AOP,Aspect Oriented Programming)是Spring框架中的一个重要特性,它提供了一种模块化和声明式的方式来处理程序中的横切关注点,如日志、事务管理、安全控制等。AOP的核心概念包括切面、通知、连接...
AOP面向切面编程.ppt
### AOP面向切面编程详解 #### 一、AOP概览 AOP(Aspect-Oriented Programming,面向切面编程)是一种编程思想和技术,它作为OOP(面向对象编程)的一种补充,主要解决了OOP在处理横切关注点方面的不足。在传统的...
面向切面编程(Aspect-Oriented Programming,AOP)是Spring框架的核心特性之一,它提供了一种优雅的方式来处理系统的横切关注点,如日志、事务管理、性能监控和权限控制等。在Spring中,AOP主要通过代理模式实现,...
面向切面编程(AOP)是一种编程范式,它旨在减少代码中的重复部分,特别是那些与核心业务逻辑无关但又必须处理的交叉关注点,如日志、事务管理、安全控制等。Spring框架是Java领域中实现AOP的常用工具,它通过提供...
面向切面编程(Aspect-Oriented Programming,AOP)是一种编程范式,旨在将系统中的关注点分离,提高代码的可重用性、可维护性和模块化。在C#中,我们可以利用Unity、PostSharp或者.NET框架自带的System.Interactive...
面向切面编程(AOP,Aspect Oriented Programming)是一种编程范式,主要目的是将系统中的关注点分离,比如日志记录、事务管理等通用功能,从核心业务逻辑中解耦出来。在Java领域,Spring框架提供了强大的AOP支持,...
面向切面编程(Aspect Oriented Programming,AOP)是一种编程范式,旨在将关注点分离,使得系统中的各个部分能够更专注于自己的核心职责,而将横切关注点(如日志、事务管理、安全检查等)抽取出来独立处理。...
面向切面编程(AOP)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。 除了类(classes)以外,AOP提供了 切面。切面对关注点进行模块化,例如横切多个类型和对象的事务管理。
面向切面编程(AOP,Aspect Oriented Programming)是Java编程中的一种重要概念,它旨在提高代码的可重用性和可维护性。AOP通过将关注点分离,使得业务逻辑和系统服务(如日志、事务管理等)可以独立发展,从而降低...
面向切面编程(AOP,Aspect Oriented Programming)是Spring框架的重要组成部分,它提供了一种在不修改原有业务代码的基础上,插入额外功能的编程模型。Spring AOP使得开发者能够更方便地实现如日志记录、事务管理、...
面向切面编程(Aspect-Oriented Programming,AOP)是Spring框架的核心特性之一,它提供了一种模块化和声明式的方式来处理系统中的横切关注点,如日志、事务管理、安全检查等。本示例代码主要展示了如何在Spring框架...
面向切面编程(Aspect-Oriented Programming,简称AOP)是一种编程范式,它旨在提高软件的模块化程度,通过将关注点分离到不同的“切面”中来实现。在.NET环境中,AOP通常通过拦截器(Interceptor)或动态代理...
面向切面编程(Aspect-Oriented Programming,AOP)是一种编程范式,旨在解决软件开发中的横切关注点,如日志记录、事务管理、权限检查等,将这些分散的代码集中管理,提高代码的可读性和可维护性。AOP在传统OOP的...
sping面向切面编程简单示例,希望给予初学者帮助
面向切面编程(Aspect-Oriented Programming,AOP)是一种编程范式,旨在将横切关注点(如日志、事务管理和安全性)从核心业务逻辑中分离出来,以提高代码的可读性和可维护性。Java语言中的AOP是通过Spring框架等库...