深入理解Spring AOP之基本概念

深入理解Spring AOP之基本概念

AOP到底是什么

Spring AOP和IOC是听到的关于Spring最频繁的两个词了。现在来重点关注AOP这个词,IOC先放一边,下面这段话摘自Spring优势中关于面向切面的介绍:

  • 面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

说到AOP,不得不提到OOP,我们知道,oop是面向对象编程,而,AOP面向切面编程其实是面向对象编程的补充.

OOP:对象作为计算主体,拥有自己的名称,状态以及接受外界消息的接口。在对象模型中,产生新对象,旧对象销毁,发送消息,响应消息就构成OOP计算模型的根本。它强调对象的“抽象”、“封装”、“继承”、“多态”。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP:它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

如下图所示:日志信息,权限信息,安全服务在三个服务中都存在,使用AOP使得这三个服务能够解耦出来

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”


AOP的一些概念

描述AOP常用的一些术语有通知(Adivce)、切点(Pointcut)、连接点(Join point)、切面(Aspect)、引入(Introduction)、织入(Weaving)

通知(Advice)

通知分为五中类型:

  1. Before

    在方法被调用之前调用

  2. After

    在方法完成后调用通知,无论方法是否执行成功
  3. After-returning

    在方法成功执行之后调用通知
  4. After-throwing

    在方法抛出异常后调用通知
  5. Around

    通知了好、包含了被通知的方法,在被通知的方法调用之前后调用之后执行自定义的行为

连接点(Join point)

A point during the execution of a program, such as the execution of a method or the handling of an exception.

比如:方法调用、方法执行、字段设置/获取、异常处理执行、类初始化、甚至是 for 循环中的某个点

理论上, 程序执行过程中的任何时点都可以作为作为织入点, 而所有这些执行时点都是 Joint point

但 Spring AOP 目前仅支持方法执行 (method execution)

切点(Pointcut)

通知(advice)定义了切面何时,那么切点就是定义切面“何处” 描述某一类 Joint points, 比如定义了很多 Joint point, 对于 Spring AOP 来说就是匹配哪些方法的执行

描述方式:

  1. 直接指定 Jointpoint 所在的方法名, 功能比较单一, 通常只支持方法级别的 AOP 框架
  2. 正则表达式
  3. 特定的描述语言, 如 AspectJ 提供的 Pointcut 描述语言

切面(Aspect)

切面是切点和通知的结合。通知和切点共同定义了关于切面的全部内容,它是什么时候,在何时和何处完成功能

引入(Introduction)

引用允许我们向现有的类添加新的方法或者属性

织入(Weaving)

组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。


Spring 对AOP的支持

AOP框架种类

  • AspectJ
  • JBoss AOP
  • Spring AOP

    Spring提供了四种各具特色的AOP支持

  • 基于代理的经典AOP
  • @AspectJ 注解驱动的切面
  • 纯POJO切面
  • 注入式AspectJ切面(适合Spring各个版本)

    前面三中都是Spring基于代理的AOP变体,因此,Spring对AOP的支持局限于方法拦截。如果AOP需求超过了简单的方法拦截范畴,那么应该考虑在ASpectJ里实现切面,利用Spring的DI把Spring BEan注入到ASpectJ切面中


    Spring实现方式

    实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

    重点关注动态代理技术

    Spring的动态代理包括两个部分:

  • JDK动态代理
      JDK动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。InvocationHandler是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编制在一起。
    
    Proxy利用InvocationHandler动态创建一个符合某一接口的实例,生成目标类的代理对象。
    
  • CGLib动态代理
        CGLib全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,可以在运行期扩展Java类与实现Java接口,CGLib封装了asm,可以再运行期动态生成新的class。和JDK动态代理相比较:JDK创建代理有一个限制,就是只能为接口创建代理实例,而对于没有通过接口定义业务方法的类,则可以通过CGLib创建动态代理。
    

    Spring AOP 框架对 AOP 代理类的处理原则是:

    1. 如果目标对象的实现类实现了接口,Spring AOP 将会采用 JDK 动态代理来生成 AOP 代理类;
    2. 如果目标对象的实现类没有实现接口,Spring AOP 将会采用 CGLIB 来生成 AOP 代理类——不过这个选择过程对开发者完全透明、开发者也无需关心。

    Spring AOP 会动态选择使用 JDK 动态代理、CGLIB 来生成 AOP 代理,如果目标类实现了接口,Spring AOP 则无需 CGLIB 的支持,直接使用 JDK 提供的 Proxy 和 InvocationHandler 来生成 AOP 代理即可。

  • 版权声明:本文为博主原创文章,未经博主允许不得转载。

    时间: 2024-12-26 01:56:52

    深入理解Spring AOP之基本概念的相关文章

    我所理解的Spring AOP的基本概念

    Spring AOP中的概念晦涩难懂,读官方文档更是像读天书,看了非常多样例后,写一些自己理解的一些spring的概念.要理解面向切面编程,要首先理解代理模式和动态代理模式. 如果一个OA系统中的一个功能是查看考勤信息,那么我们如果有要实现这个功能,要经历的步骤是: 1.启动日志,进行记录. 2.启动安全性的框架进行安全检验 3.验证权限 4.假设有权限,则查看考勤记录,假设无权限,则输出没有权限. 我们的目标方法是查看考勤记录,而前面运行了那么多与目标方法无关的方法. 那些与业务逻辑无关的方法

    深入理解Spring AOP之二代理对象生成

    深入理解Spring AOP之二代理对象生成 spring代理对象 上一篇博客中讲到了Spring的一些基本概念和初步讲了实现方法,当中提到了动态代理技术,包含JDK动态代理技术和Cglib动态代理 动态代理这部分我有过一篇博客介绍:动态代理,想深入了解的朋友能够看一看,再回想一下,Spring中怎样区分採用JDK动态代理和CGlib动态代理: 假设目标对象的实现类实现了接口.Spring AOP 将会採用 JDK 动态代理来生成 AOP 代理类: 假设目标对象的实现类没有实现接口,Spring

    Spring AOP那些学术概念—通知、增强处理连接点(JoinPoint)切面(Aspect)

    1.我所知道的AOP 初看起来,上来就是一大堆的术语,而且还有个拉风的名字,面向切面编程,都说是OOP的一种有益补充等等.一下让你不知所措,心想着:管不得很多人都和我说AOP多难多难.当我看进去以后,我才行发现:他就是一些Java基础上的朴实无华的应用,包括IOC(见<Spring IOC(依赖注入.控制反转)概念理解>),包括许许多多这样的名词,都是万变不离其宗而已. 2.为什么要用AOP 1)就是为了方便,看一个国外很有名的大师说,编程的人都是“懒人”,因为他把自己做的事情都让程序去做了.

    Spring AOP(一)--基本概念

    AOP(Aspect Oriented Programing),意为面向切面编程,其实看了很多书本的介绍和说明,我觉得这些解释都太过书面,也可能是翻译的原因,总觉得还是不太懂,也难以理解这种叫法,尤其是这个切面.其实切面在数学中指的是“和球面只有一个交点的平面”,我猜测spring团队之所以这么起名应该也是受了这种数学思想的启发,所以我也以这个为出发点去理解它.面向切面编程,假设我的某个业务逻辑是一个球,有一个切面和它相交于一点,所以它们互不干扰,只是通过这个切点连接,帮助我们完成一些功能,我觉

    如何简单理解spring aop和事务

    用比喻的方法理解吧: 初学者的理解,仅仅为了个人好记 aop:由三部分组成:工具箱,工人,为工人分配工具 tx事务:由四部分组成:管理者,制度,工人,向工人通知管理制度  为什么这样理解呢?个人觉得好记: 在aop 中有切面:切面内的东西用来公共使用,类似于工具箱: ref就是这个工具箱的具体bean.. <aop:aspect id="***" ref="*****"> 切点:切点是许多符合切点表达式的东西,只要符合就可以使用公共的东西.根据表达式,挑

    正确理解Spring AOP中的Around advice

    Spring AOP中,有Before advice和After advice,这两个advice从字面上就可以很容易理解,但是Around advice就有点麻烦了. 乍一看好像是Before advice和After advice的组合,也就是说pointcut会在joinpoint执行前后各执行一次.但是这种理解是不正确的,如果这样理解的话,就会产生这样的疑问:spring aop Around类型为什么只执行一次 ,这个帖子是我碰巧看到. 那么怎么样理解才是正确的呢?我们来看一下Spri

    Spring学习十三----------Spring AOP的基本概念

    ? 版权声明:本文为博主原创文章,转载请注明出处 什么是AOP -面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术 -主要的功能是:日志记录.性能统计.安全控制.事务处理.异常处理等 AOP实现方式 -预编译 -AspectJ -运行期动态代理(JDK动态代理.CGLib动态代理) -Spring AOP.Jboss AOP AOP相关概念 -切面(Aspect)   一个关注点的模块化,这个关注点可能会横切多个对象 -连接点(Joinpoint)   程序执行过程中

    Spring aop 原始的工作原理的理解

    理解完aop的名词解释,继续学习spring aop的工作原理. 首先明确aop到底是什么东西?又如何不违单一原则并实现交叉处理呢? 如果对它的认识只停留在面向切面编程,那就脏了.从oop(Object Oriented Programming)说起,oop引入封装,多态,继承等概念建立对象层次的结构,处理公共行为属性的集合.对于一个系统而言,需要把分散对象整合到一起的时候,oop就虚了,因为这样的需求已经在对象层次之上了.如订单模块,还款模块都需要User对象配合(当然不止于User对象完成的

    Spring AOP深入理解之拦截器调用

    Spring AOP深入理解之拦截器调用 Spring AOP代理对象生成回想 上一篇博客中:深入理解Spring AOP之二代理对象生成介绍了Spring代理对象是怎样生成的,当中重点介绍了JDK动态代理方式,简单回想下代理对象生成过程: 1.上面讲到了两种生成代理对象的方法,一种是通过ProxyFactory,一种是通过ProxyFactoryBean. 第一种获取比較简单,可是须要手工的进行写代码.而另外一种是通过Spring的IOC机制来控制Bean的生成. 2.不管是ProxyFact