假设有若干数据访问对象(DAO),都要实现对一个数据对象的访问。因此,为了保持数据同步,需要对这个数据对象加锁。这样,每个DAO都要自己管理有关 “锁”的内容。而DAO真正应该实现的逻辑是关于数据对象的访问,锁乃其身外之物,而且每个DAO都要实现关于锁的业务逻辑,所以有没有办法把锁的管理从 DAO中抽离出来呢?这个就是AOP所关心的。
AOP本身也是用OOP实现的,但是如下图所示,它更关心的是与其它业务逻辑流程相垂直的,且是其他业务逻辑所共有的一些东西。因此,当把对“锁”的管理 从各个DAO中抽离出来之后,你会发现,这个管理锁的类本身实现了一个关于“锁”的方面的业务逻辑。它就像一道关卡,垂直切入了DAO的业务流程,单独构 成了一个方面。
如下图
其中锁处理,就是AOP的编程,它包括了什么时候处理和怎样处理,也就是以后AOP概念中的联结点和通知。
关于AOP相关概念理解
联接点(Jointpoint)是一个程序执行过程中的特定时刻。例如方法调用的时候,类初始化的时候,之类的。但是Spring的联结点就一个——方法调用。另外,要注意的是,程序执行的过程本身,也可以抽象成一个联接点,只不过Spring不支持罢了。联结点,说白了,就是一个事件,它告诉AOP什么时候调用通知。在Spring中就联接点就意味这一件事,出现方法调用的时候,就该通知出场执行AOP业务逻辑了。
通知(Advice),就是下面大括号所指向的部分哦。说白了,所谓通知就是实现AOP业务逻辑的地方,也就是说,通知是你应该实现的,具体如何处理AOP业务逻辑的类。根据通知出现位置的不同,即其业务逻辑所覆盖的范围不同,称呼也不同。Spring中一共五种通知:
- 前置通知(MethodBeforeAdvice)
- 后置通知(AfterReturningAdvice)
- 包围通知(MethodIntercepter)
- 抛出通知(ThrowAdvice)
- 引入(IntroductionIntercepter)
怎么理解这5中通知呢?不妨打个比喻,假设你是老板,你手下有个高参(AOP)。
现在,你要投资一个项目了(联接点,这里比喻方法调用)。你的高参会在你投资前,提前给你一份企划书,其中包括了这个投资(方法调用)之前应该怎么准备 (在联接点之前应该做些什么预处理AOP逻辑)、投资过程和投资后应该注意些什么(方法调用结束之后做些什么)。这个企划书事关全局,整个就是围绕这你的 投资展开的,你的投资(方法调用)只是其中的一部分,那么这个建议就相当于Spirng AOP中的包围通知.
它可以在目标方法(投资)执行之前或之后运行,也可以自定义什么时候调用目标方法(别忘了出企划的是高参,它自身可以考虑什么时候帮助你执行企划中的特别部分),当然也可以自己编写逻辑嗲用完全不同的目标方法(如果以前的企划不成立,就重新确立一个吧)。
当然,企划和具体实施是两码事。当要具体实施的时候(投资前,即方法调用之前),发生了一些变数,要针对这些变数进行修正,并使其朝着有利于投资的方面发展,这些工作即提前建议,(Advice这个词,在Spring AOP中被翻译为通知),换成Spring的AOP术语就是前置通知。
前置通知可以访问被调用的目标方法(高参当然首先要知道你要干什么,然后才能告诉你该怎么干)和参数(高参给你准备的一些额外的关系和投资建议等等,帮助 你决策如何投资),但是它不能影响方法调用本身(因为高参不是你,所以它不是老板,自然不能决定是否要投资,它只能提建议——advice)。
貌似一切顺利的执行了投资,但是在投资过程中你这个老板发现,有些问题是你之前没有预料到的,这些确实是个意外。所以你将这些意外告诉了你的高参(抛出异 常)。高参不愧是高参,人家早就想到了(但是“我就是不说”——《电梯》,姜昆相声中的台词)。于是立即调用了特别准备的应急预案,对异常进行处理。换作 Spring AOP的术语就是抛出通知。
抛出通知使得我们可以根据需要只接受到特定的异常(高参关心的是某些严重问题,一般问题老板都可以自己摆平了~~),这样,就可以知道哪里出了异常——出现异常的方法、目标方法和其参数。
投资结束了,你的盈利或许会比预期的多,或许少于预期。你让高参帮忙分析,此时高参手里早就握有你投资前的准备,还有你投资的过程以及投资的结果,高参会根据这些资料分析你的得失,做出进一布调整的建议,帮你调整决策。这个么,就是后置通知。
显然,方法调用已经完成。它可以访问的有被调用的目标方法(投资项目),该方法的参数(投资的准备工作和使用的决策等)和返回值(当然是投资的结果)。因 为方法调用已经完成,所以后置通知完全不能影响方法调用本身的事情。(对于既定的事实,无论是成功还是失败,高参都只能根据过去向前看,当然不能改变过去 了)
关于引入通知。Spring其实将引入过程当成一个特殊的拦截器,就是一旦发生引入了,Spring就给他拦截下来,并执行相应的处理。就好比,一旦有人要入关,那么就会接到海关的盘查一样。关于引入通知的内容,以后会详述。
在解释关于切入点(Pointcut)的概念之前,先看下图。
正像定义中所说的那样,切入点其实就是一组联接点。在Spring中就可以理解为某个类实例的所有方法的调用(图中紫色实心圆)。我们不关心方法被调用的时间,只关心它是否是即将被调用的这个事件。因为Spring中的联接点只有一种——方法调用,所以切入点也只能有一种,方法调用这个事件所组成的集合。
继续用高参来解释。就是说高参给你建议的前提是,不在乎你做出什么时候决策(投资、会见客人或者其他),而是,当你做出决策这件事情的发生。当高参看到你 要做决策了,他就会在你做决策前给你建议(Advice,通知)。也正式因为有了这个机制,所以你才能在做每件商业活动的时候都能精确的受到来自高参的建 议,也就是Spring AOP中所讲的,精确的控制程序中什么组件(操作)接到什么通知。
所谓方面(Aspect), 就是通知和切入点的组合。换言之,它是一揽子解决方案,即你的商业决策(投资、会见客人或者其他)和高参根据这些决策给你的不同的建议(Advice,通 知)。呵呵,到这里说AOP就更明白了。你,老板,执行的是线性商业(business,业务)逻辑,而你的高参(AOP),则在你身旁,根据你的决策提 建议,帮你从即要自己提自己的建议又要执行商业逻辑的苦恼中解脱出来,好让你可以专心的经营生意。这个不就是AOP的真谛么!它不在于取代你(OOP)的 位置,它只是帮助你,让你少点烦心事,更能关注你自己的业务。另外AOP本身不也是OOP写的么(难道老板是人类,高参就不是人类)。虽然,你缺少高参一 样能干活,但是累。正像OOP没有AOP也一样能工作。但是AOP没了OOP的基础就不成(因为首先是人类才有肯能成为你的高参,动物没这个能力吧;另一 方面,也说明了高参这个群体没有老板群体,也就失去了存在的意义,失业了)。
织入(Weaving),可以理解成为高参的建议是如何被你采纳的方式(过程)。如果 是你事先就把高参的建议背的滚瓜乱熟、了然于胸,那么遇到相应的情况自然会采取相应的对策。这个就是静态AOP的意义,将AOP逻辑直接写入到目标类的字 节码中,好让目标类的字节码文件可以像调用自身方法一样调用AOP业务逻辑,所以效率高。但是遇到高参也没有预料的情况,就只能傻眼了(回去问高参的话, 那个是动态AOP了)。但是如果你开始根本就没有看高参的建议,那么遇到了相应的情况自然临时抱佛脚,赶紧去看高参的建议,自然效率低。这个就是动态的 AOP,可以勉强这么理解。缺点是效率低,优点是,可能有些情况高参原来也没有遇到,所以你这个时候求助于高参,也会得到解答。
目标(Target),当然就是高参提供建议给他的对象了,也就是你,老板了。
引入(Introduction)。OK,终于遇到你自己无法解决的问题了,而且这个问题用 高参的建议也不成,怎么办?这个时候高参亲自出面代替你了,帮你摆平,当然铲事儿的手段是你所不具备的,这个就是引入。引入的目的就是在一个对象中加入新 的方法或者属性,以改变它的结构,帮助你完成原来不能完成的事情。
转载自http://blog.sina.com.cn/s/blog_3e93e9fa010009ib.html
另参考http://blog.csdn.net/zhangjiawei520/article/details/7474923
http://www.cnblogs.com/xiaoluo501395377/archive/2012/10/20/2732083.html
http://www.cnblogs.com/xiaoluo501395377/archive/2012/10/20/2732083.html