AOP

What is AOP?AOP即Aspect-Oriented Programming的缩写,中文意思是面向切面编程,也有译作面向方面编程的,因为Aspect有“方面、见地”的意思。AOP实际上是一种编程思想,由Gregor Kiczales在Palo Alto研究中心领导的一个研究小组于1997年提出[1]。在传统的面向对象(Object-Oriented Progr amming,OOP)编程中,对垂直切面关注度很高,横切面关注却很少,也很难关注。也就是说,我们利用OOP思想可以很好的处理业务流程,却不能把系统中的某些特定的重复性行为封装在某个模块中。比如在很多的业务中都需要记录操作日志,结果我们不得不在业务流程种嵌入大量的日志记录代码。无论是对业务代码还是对日志记录代码来说,今后的维护都是非常复杂的。由于系统种嵌入了这种大量的与业务无关的其它重复性代码,系统的复杂性、代码的重复性增加了,从而使bug的发生率也大大的增加。

       在OOP面向对象编程中,我们总是按照某种特定的执行顺序来实现业务流程,各个执行步骤之间是相互衔接、相互耦合的。比如某个对象抛出了异常,我们就必须对异常进行处理后才能进行下一步的操作;又比如我们要把一个学生记录插入到教务管理系统的学生表中去,那么我们就必须按照注册驱动程序、连接数据库、创建一个statement、生成并执行SQL语句、处理结果、关闭JDBC对象等步骤按部就班的编写我们的代码。可以看到上面的步骤种除了执行SQL和处理结果是我们业务流程所必须的外,其它的都是重复的准备和殿后工作,与业务流程毫无关系,另外我们还得要考虑程序执行过程中的异常。天!我们只是需要向一张表中插入数据而已,可是却不得不和这些大量的重复代码纠缠在一起,我们不得不把大量的精力用在这些代码上而无法专心的设计业务流程。

       那么什么可以解决这个问题呢?这时候,我们需要AOP,关注系统的“截面”,在适当的时候“拦截”程序的执行流程,把程序的预处理和后处理交给某个拦截器来完成。比如在操作数据库时要记录日志,如果使用AOP的编程思想,那么我们在处理业务流程时不必再考虑日志记录,而是把它交给一个特定的日志记录模块去完成。这样,业务流程就完全的从其它无关的代码中解放出来,各模块之间的分工更加明确,程序维护也变得容易多了。

      正如上所说,AOP不是一种技术,而是编程思想。凡是符合AOP思想的技术,都可以看成是AOP的实现。目前的AOP实现有AspectJ、JBoss4.0、nanning、spring等项目。其中Spring对AOP进行了很好的实现,同时Spring AOP也是Spring的两大核心之一。

 

 

 

AOP为Aspect Oriented Programming的缩写,意为:面向方法编程,可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。

 

<script type="text/javascript"></script>

简介

   面向切面编程(也叫面向方面):Aspect Oriented Programming(AOP),是目前软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。   AOP是OOP的延续,是(Aspect Oriented Programming)的缩写,意思是面向切面(方面)编程。   主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。   主要的意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改
   AOP

 

变这些行为的时候不影响业务逻辑的代码。   可以通过预编译方式和运行期动态代理实现在不修改 源代码 的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF 设计模式 的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,AOP可以说也是这种目标的一种实现。   在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。   Aspect Oriented Programming(AOP)是近来较为热门的一个话题。AOP,国内   大致译作“ 面向方面编程 ”。   “面向方面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。笔者不止   一次听到类似“OOP/OOD11即将落伍,AOP是新一代软件开发方式”这样的发言。显然,   发言者并没有理解AOP的含义。   Aspect,没错,的确是“方面”的意思。不过,华语传统语义中的“方面”,大多数情   况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要   从几个方面来看待”,往往意思是:需要从不同的角度来看待同一个事物。这里的“方面”,   指的是事务的外在特性在不同观察角度下的体现。   而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。所以笔者更倾向   于“面向切面编程”的译法。   另外需要提及的是,AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种   设计思想。OOP( 面向对象编程 )针对业务处理过程的实体及其属性和行为进行抽象封装,   以获得更加清晰高效的 逻辑单元 划分。   而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步   骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有   着本质的差异。   上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样一个业务实体进行封   装,自然是OOP/OOD的任务,我们可以为其建立一个“Employee”类,并将“雇员”相   关的属性和行为封装其中。而用AOP设计思想对“雇员”进行封装将无从谈起。   同样,对于“权限检查”这一动作片断进行划分,则是AOP的目标领域。而通过OOD/OOP   对一个动作进行封装,则有点不伦不类。   换而言之,OOD/OOP面向名词领域,AOP面向动词领域。

应用举例

  假设有在一个应用系统中,有一个共享的数据必须被并发同时访问,首先,将这个数据封装在数据对象中,称为Data Class,同时,将有多个访问类,专门用于在同一时刻访问这同一个数据对象。   为了完成上述并发访问同一资源的功能,需要引入锁Lock的概念,也就是说,某个时刻,当有一个访问类访问这个数据对象时,这个数据对象必须上锁Locked,用完后就立即解锁unLocked,再供其它访问类访问。   使用传统的编程习惯,我们会创建一个抽象类,所有的访问类继承这个抽象父类,如下:   abstract class Worker{   abstract void locked();   abstract void accessDataObject();   abstract void unlocked();   }

缺点:

  accessDataObject()方法需要有“锁”状态之类的相关代码。   Java只提供了单继承,因此具体访问类只能继承这个父类,如果具体访问类还要继承其它父类,比如另外一个如Worker的父类,将无法方便实现。   重用被打折扣,具体访问类因为也包含“锁”状态之类的相关代码,只能被重用在相关有“锁”的场合,重用范围很窄。   仔细研究这个应用的“锁”,它其实有下列特性:   “锁”功能不是具体访问类的首要或主要功能,访问类主要功能是访问数据对象,例如读取数据或更改动作。   “锁”行为其实是和具体访问类的主要功能可以独立、区分开来的。   “锁”功能其实是这个系统的一个纵向切面,涉及许多类、许多类的方法。如下图:   因此,一个新的程序结构应该是关注系统的纵向切面,例如这个应用的“锁”功能,这个新的程序结构就是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可以让我们从一个更高的抽象概念来理解软件系统,AOP也许提供一种有价值的工具。可以这么说:因为使用AOP结构,现在JBoss 4.0的源码要比JBoss 3.X容易理解多了,这对于一个大型复杂系统来说是非常重要的。   从另外一个方面说,好像不是所有的人都需要关心AOP,它可能是一种架构设计的选择,如果选择J2EE系统,AOP关注的上述通用方面都已经被J2EE容器实现了,J2EE应用系统开发者可能需要更多地关注行业应用方面aspect。

AOP具体实现

  AOP是一个概念,并没有设定具体语言的实现,它能克服那些只有单继承特性语言的缺点(如Java),目前AOP具体实现有以下几个项目:   AspectJ (TM): 创建于Xerox PARC. 有近十年历史,成熟   缺点:过于复杂;破坏封装;需要专门的Java 编译器   动态AOP:使用JDK的动态代理API或字节码Bytecode处理技术。   基于动态代理API的具体项目有:   JBoss 4.0 JBoss 4.0服务器   nanning 这是以中国 南宁 命名的一个项目,搞不清楚为什么和中国相关?是中国人发起的?   基于字节码的项目有:   aspectwerkz ,spring

AOP 能够给我们带来什么

  面向过程编程离我们已经有些遥远,面向对象编程正主宰着 软件 世界。当每个新的 软件设计师 都被要求掌握如何将需求功能转化成一个个类,并且定义它们的数据成员、行为,以及它们之间复杂的关系的时候,面向方面编程(Aspect-Oriented Programming,AOP)为我们带来了新的想法、新的思想、新的模式。   如果说面向对象编程是关注将需求功能划分为不同的并且相对独立,封装良好的类,并让它们有着属于自己的行为,依靠继承和 多态 等来定义彼此的关系的话;那么面向方面编程则是希望能够将通用需求功能从不相关的类当中分离出来,能够使得很多类共享一个行为,一旦发生变化,不必修改很多类,而只需要修改这个行为即可。   面向方面编程是一个令人兴奋不已的新模式。就开发软件系统而言,它的影响力必将会和有着十数年应用历史的面向对象编程一样巨大。面向方面编程和面向对象编程不但不是互相竞争的技术而且彼此还是很好的互补。面向对象编程主要用于为同一对象层次的公用 行为建模 。它的弱点是将公共行为应用于多个无关对象模型之间。而这恰恰是面向方面编程适合的地方。有了 AOP,我们可以定义交叉的关系,并将这些关系应用于跨模块的、彼此不同的对象模型。AOP 同时还可以让我们层次化功能性而不是嵌入功能性,从而使得代码有更好的可读性和易于维护。它会和面向对象编程合作得很好。   AOP 的应用范围   传统的程序通常表现出一些不能自然地适合单一的程序模块或者是几个紧密相关的程序模块的行为,AOP 将这种行为称为横切,它们跨越了给定编程模型中的典型职责界限。横切行为的实现都是分散的,软件设计师会发现这种行为难以用正常的逻辑来思考、实现和更改。最常见的一些横切行为如下面这些:   日志记录,跟踪,优化和监控   事务的处理   持久化   性能的优化   资源池,如 数据库连接池 的管理   系统统一的认证、权限管理等   应用系统的异常捕捉及处理   针对具体行业应用的横切行为   目前,前面几种横切行为都已经得到了密切的关注,也出现了各种有价值的应用,但也许今后几年,AOP 对针对具体行业应用的贡献会成为令人关注的焦点。   AOP 的具体实现   AOP 是一个概念,一个规范,本身并没有设定具体语言的实现,这实际上提供了非常广阔的发展的空间。AspectJ是AOP的一个很悠久的实现,它能够和 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 并没有帮助我们解决任何新的问题,它只是提供了一种更好的办法,能够用更少的工作量来解决现有的一些问题,并且使得系统更加健壮,可维护性更好。同时,它让我们在进行系统架构和模块设计的时候多了新的选择和新的思路。   AOP 和 OOP 到底是什么关系   很多人在初次接触 AOP 的时候可能会说,AOP 能做到的,一个定义良好的 OOP 的接口也一样能够做到,我想这个观点是值得商榷的。AOP和定义良好的 OOP 的接口可以说都是用来解决并且实现需求中的横切问题的方法。但是对于 OOP 中的接口来说,它仍然需要我们在相应的模块中去调用该接口中相关的方法,这是 OOP 所无法避免的,并且一旦接口不得不进行修改的时候,所有事情会变得一团糟;AOP 则不会这样,你只需要修改相应的 Aspect,再重新编织(weave)即可。 当然,AOP 也绝对不会代替 OOP。核心的需求仍然会由 OOP 来加以实现,而 AOP 将会和 OOP 整合起来,以此之长,补彼之短。   AOP 适合工业化的应用吗?   这个问题很难回答,其实最好的答案就是尝试,用成功的项目或是产品来回答。Jboss 4.0 就是完全采用 AOP 的思想来设计的 EJB 容器,它已经通过了 J2EE 的认证,并且在工业化应用中证明是一个优秀的产品。相信在不远的将来,会出现更多采用 AOP 思想设计的产品和行业应用。   小结   AOP 正向我们走来,我们需要关注的是怎么样使得它能够为我们的软件系统的设计和实现带来帮助。本文旨在给大家一点启发,能够在更多的领域更深入的应用 AOP 的思想。

你可能感兴趣的:(AOP)