在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。AOP在其他领域也有其他含义。
aop_AOP -名称含义
AOPAspect Oriented Programming(AOP)是较为热门的1个话题。AOP,国内大致译作“面向方面编程”。
[]“面向方面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。笔者不止一次听到类似“OOP/OOD11即将落伍,AOP是新一代软件开发方式”这样的发言。显然,发言者并没有理解AOP的含义。Aspect,没错,的确是“方面”的意思。不过,华语传统语义中的“方面”,大多数情况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要从几个方面来看待”,往往意思是:需要从不同的角度来看待同1个事物。这里的“方面”,指的是事物的外在特性在不同观察角度下的体现。而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。所以笔者更倾向于“面向切面编程”的译法。
可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的1种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的1种实现。
在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。
主要功能
日志记录,性能统计,安全控制,事务处理,异常处理等等
主要意图
将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为之际不影响业务逻辑的代码。
aop_AOP -AOP/OOP
区分
AOP、OOP在字面上虽然非常类似,但却是面向不同领域的2种设计思想。OOP( 面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的 逻辑单元划分。
而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低 耦合性的隔离效果。这2种设计思想在目标上有着本质的差异。
上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样1个 业务实体进行封装,自然是OOP/OOD的任务,我们可以为其建立1个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP设计思想对“雇员”进行封装将无从谈起。
同样,对于“权限检查”这一动作片断进行划分,则是AOP的目标领域。而通过OOD/OOP对1个动作进行封装,则有点不伦不类。
换而言之,OOD/OOP面向名词领域,AOP面向动词领域。
关系
很多人在初次接触 AOP 之际可能会说,AOP 能做到的,1个定义良好的 OOP 的接口也一样能够做到,我想这个观点是值得商榷的。AOP和定义良好的 OOP 的接口可以说都是用来解决并且实现需求中的横切问题的方法。但是对于 OOP 中的接口来说,它仍然需要我们在相应的模块中去调用该接口中相关的方法,这是 OOP 所无法避免的,并且一旦接口不得不进行修改之际,所有事情会变得一团糟;AOP 则不会这样,你只需要修改相应的 Aspect,再重新编织(weave)就可以。 当然,AOP 也绝对不会代替 OOP。核心的需求仍然会由 OOP 来加以实现,而 AOP 将会和 OOP 整合起来,以此之长,补彼之短。
aop_AOP -主要缺点
accessDataObject()方法需要有“锁”状态之类的相关代码。
Java只提供了单继承,因此具体访问类只能继承这个父类,如果具体访问类还要继承其它父类,比如另外1个如Worker的父类,将无法方便实现。
重用被打折扣,具体访问类因为也包含“锁”状态之类的相关代码,只能被重用在相关有“锁”的场合,重用范围很窄。
仔细研究这个应用的“锁”,它其实有下列特性:
“锁”功能不是具体访问类的首要或主要功能,访问类主要功能是访问数据对象,例如读取数据或更改动作。
“锁”行为其实是和具体访问类的主要功能可以独立、区分开来的。
“锁”功能其实是这个系统的1个纵向切面,涉及许多类、许多类的方法。如下图:
因此,1个新的程序结构应该是关注系统的纵向切面,例如这个应用的“锁”功能,这个新的程序结构就是aspect(方面)
在这个应用中,“锁”方面(aspect)应该有以下职责:
提供一些必备的功能,对被访问对象实现加锁或解锁功能。以保证所有在修改数据对象的操作之前能够调用lock()加锁,在它使用完成后,调用unlock()解锁。
AOP应用范围
很明显,AOP非常适合开发J2EE容器服务器,目前JBoss 4.0正是使用AOP框架进行开发。
具体功能如下:
Authentication 权限
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 懒加载
Debugging调试
logging, tracing, profiling and monitoring 记录跟踪 优化 校准
Performance optimization 性能优化
Persistence持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务
【AOP有必要吗?】
当然,上述应用范例在没有使用AOP情况下,也得到了解决,例如JBoss 3.XXX也提供了上述应用功能,但是没有使用AOP。
但是,使用AOP可以让我们从1个更高的抽象概念来理解软件系统,AOP也许提供1种有价值的工具。可以这么说:因为使用AOP结构,现在JBoss 4.0的源码要比JBoss 3.X容易理解多了,这对于1个大型复杂系统来说是非常重要的。
从另外1个方面说,好像不是所有的人都需要关心AOP,它可能是1种架构设计的选择,如果选择J2EE系统,AOP关注的上述通用方面都已经被J2EE容器实现了,J2EE应用系统开发者可能需要更多地关注行业应用方面aspect。
【AOP具体实现】
AOP是1个概念,并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点(如Java),目前AOP具体实现有以下几个项目:
AspectJ (TM): 创建于Xerox PARC. 有近十年历史,成熟
缺点:过于复杂;破坏封装;需要专门的Java编译器。
动态AOP:使用JDK的动态代理API或字节码Bytecode处理技术。
基于动态代理API的具体项目有:
JBoss 4.0 JBoss 4.0服务器
nanning 这是以中国南宁命名的1个项目,搞不清楚为什么和中国相关?是中国人发起的?
基于字节码的项目有:
aspectwerkz
spring ?
aop_AOP -作用
面向过程编程离我们已经有些遥远, 面向对象编程正主宰着 软件世界。当每个新的 软件设计师都被要求掌握如何将需求功能转化成1个个类,并且定义它们的 数据成员、行为,以及它们之间复杂的关系之际,面向切面编程(Aspect-Oriented Programming,AOP)为我们带来了新的想法、新的思想、新的模式。
如果说 面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和 多态等来定义彼此的关系的话;那么面向切面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享1个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为就可以。
面向切面编程是1个令人兴奋不已的新模式。就开发 软件系统而言,它的影响力必将会和有着数十年应用历史的 面向对象编程一样巨大。 面向 切面编程和 面向对象编程不但不是互相竞争的技术而且彼此还是很好的互补。 面向对象编程主要用于为同一对象层次的公用 行为建模。它的弱点是将公共行为应用于多个无关对象模型之间。而这恰恰是 面向 切面编程适合的地方。有了 AOP,我们可以定义交叉的关系,并将这些关系应用于跨模块的、彼此不同的对象模型。AOP 同时还可以让我们层次化功能性而不是嵌入功能性,从而使得代码有更好的可读性和易于维护。它会和 面向对象编程合作得很好。
aop_AOP -实现
AOP 是1个概念,1个规范,本身并没有设定具体语言的实现,这实际上提供了非常广阔的发展的空间。AspectJ是AOP的1个很悠久的实现,它能够和 Java 配合起来使用。
介绍 AspectJ 的使用和编码不是本文的目的,你可以在 Google 上找到很多有关它的材料。
这里只是重温 AspectJ 中几个必须要了解的概念:
Aspect: Aspect 声明类似于 Java 中的类声明,在 Aspect 中会包含着一些 Pointcut 以及相应的 Advice。
Joint point:表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及 异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Pointcut:表示一组 joint point,这些 joint point 或是通过逻辑关系组合起来,或是通过通配、 正则表达式等方式集中起来,它定义了相应的 Advice 将要发生的地方。
Advice:Advice 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
下面要讨论的这些问题,也许正是接触了 AOP 之后所困惑的。
AOP 帮助我们解决了新的问题没有?
AOP 并没有帮助我们解决任何新的问题,它只是提供了1种更好的办法,能够用更少的工作量来解决现有的一些问题,并且使得系统更加健壮,可维护性更好。同时,它让我们在进行系统架构和 模块设计之际多了新的选择和新的思路。
aop_AOP -工业化应用
这个问题很难回答,其实最好的答案就是尝试,用成功的项目或是产品来回答。Jboss 4.0 就是完全采用 AOP 的思想来设计的 EJB 容器,它已经通过了 J2EE 的认证,并且在工业化应用中证明是1个优秀的产品。相信在不远的将来,会出现更多采用 AOP 思想设计的产品和行业应用。
aop_AOP -小结
AOP 正向我们走来,我们需要关注的是怎么样使得它能够为我们的 软件系统的设计和实现带来帮助。本文旨在给大家一点启发,能够在更多的领域更深入的应用 AOP 的思想。