Spring core 源码分析 ---- AOP(一) Spring AOP介绍

1.什么是 AOP?

     Aspect-Oriented Programming(AOP,面向切面编程)是对Object-Oriented Programming(OOP面向对象编程) 在设计程序结构时的一种完善和补充,而这一切的理念都是从模块化思想开始的。在OOP中最关键的组件单元是类,而对于AOP来讲是aspect(切面)。

    OOP是一种非常成功、极具表现力的编程范式,它将概念自然地表达为对象,从而将其中通用的代码模块化。所以,衡量OOP设计成功与否的标准就是它在多大程度上避免了代码的重复。

    一般情况下,OOP能够很好地避免代码重复。继承可以帮助我们再不同类型之间共享相同的行为;继承可以帮助我们在不同类型之间共享相同的行为;多态让我们可以用同样的方 式来处理不同类型之间的对象,能够让我们将注意力集中在他们的共同之处。但当遇上一些特定问题的时候,比如,当我们需要为分散的对象引入公共行为时,OOP就显得很无力了。也就是说,OOP很适合你定义从上到下的关系,但不适合定义水平的关系。可以说因为有这些Bug的存在,是AOP生成的直接诱因,所以是为了弥补OOP而存在的。AOP在看待应用程序结构的方式上与OOP是截然不同的,以AOP的思路来看,系统是被分解成方面(Aspect)或者关注点(Concern),而不是一个个对象。追根溯源,与OOP一样,AOP只不过是一种全新的模块化机制而已,他的主要作用是用来描述分散在对象、类或函数中的横切关注点,从关注点中分离出横切关注点则是 AOP的核心概念。

    AOP的原理,也是非常简单的,即通过分离关注点让解决特定领域问题的代码从业务逻辑中独立出来,业务逻辑的代码中就不再含有针对特定领域问题代码的调用,业务逻辑同特定领域问题的关系则通过切面来封装、维护,这样原本分散在整个应用程序中的代码就可以很好的进行管理了。例如:在使用公共函数的时候,往往需要进行一些逻辑设计,也就时需要代码实现来支持,而这些逻辑代码也是需要维护的,在传统的公共子模块的调用中,除了直接调用以外就没有其他的手段。而相同的情况,在使用AOP后,不仅可以将这些重复的代码抽出来单独维护,而且可以在需要时进行统一调度,这样的使用方法虽然与设计公共子模块有几分相似,但他为这一类问题的解决提供了一整套完整的理论和灵活多样的实现方法。也就是说,在AOP提出横切概念以后,再把模块功能正交化的同时,也在此基础上提供了一系列横切的灵活实现。

2.AOP中的概念介绍

 

AOP中的概念:

Aspect(切面):一个关注点的模块,可能横切多个对象。在J2EE中,事务管理是一个横切关注点的典型例子。切面一般由 配置文件 或者 @Aspect的注解实现。

Join point(连接点): 程序一个明确的执行点,例如方法的执行以及异常的抛出(捕获)。一个切点总是跟随一个方法的执行。

Advice(增强) : 一个切面在特定的连接点执行的动作。 advice 有 "around" ,"before","after" 等不同类型。在Spring AOP中,将一个增强可以被看做一个interceptor(拦截器),而 一个切点 维护一个 拦截器的链。

PointCut(切点): 匹配连接点的配置。Advice 就是通过PointCut的表达式 找到多有匹配的连接点(比如一个指定方法的执行)。而PointCut的配置对于AOP 找到JoinPoint 是至关重要的,Spring 默认使用AspectJ的PointCut表达式语言。

Introduction(引入):添加方法或字段到增强化类。

Target object(目标):被一个或多个切面增强的对象,也叫advised object。

AOP proxy(代理): AOP框架创建的对象,用来实现切面里方法的执行等。 Spring里用的是JDK动态代理或CGLIB代理

Weaving(织入): 通过其他应用类型或对象连接切面去创建增强对象。可以在编译时完成(使用AspectJ compiler),加载时和运行时完成。 而Spring 与其他 纯Java AOP框架一样,在运行时织入。

AOP增强类型:

Before advice(前置增强): 在连接点执行之前的增强,此增强不能阻止流程继续执行到连接点(除非抛出异常)

After returning advice(正常返回增强):在连接点正常完成后执行的增强,例如,如果一个正常返回,没有抛出异常。如果抛出异常则不会执行。

After throwing advice (异常抛出增强): 方法存在并抛出异常时执行。

After(finally) advice(后置增强): 只要连接点存在,不管异常还是正常返回都会执行

Around advice(环绕增强): 包围一个连接点的增强,如方法调用,是最强大的增强。在方法调用前后完成自定义的行为。它们负责选择继续执行连接点或直接返回它们自己的返回值或抛出异常来执行。

 

3.Spring AOP 简介

    Spring AOP是纯Java实现的,不需要特别的编译过程,也不需要去控制class loader hierarchy,所以特别适合在Servlet容器与application server中使用。

     Spring AOP现在只支持增强beans的方法执行,若要实现属性的监测,可以使用AspectJ。因此,为了提供更加丰富的AOP解决方案,Spring对Aspectj做了集成。同时,再配合Spring的IOC容器,Spring推出了一个完善的AOP解决方法。

    Spring AOP 中的AOP代理默认使用的是标准的JDK动态代理。它能作用于任何借口(或一系列接口)。Spring AOP也使用CGLIB代理,CGLIB主要用来代理类而不是接口,例如一个业务对象没有实现任何一个接口时。但是,正常情况下,较好的编程实践是,业务对象大多数都会实现一个到多个接口。Spring AOP也可以配置成强制使用CGLIB,这种情况就是你必须增强一个没有在接口声明的方法,或者你必须将代理对象作为一个方法的Proxy类型的参数来传递。

    在做使用到Spring AOP相关设计时,

    一定会考虑使用 Spring AOP 还是 完整的AspectJ?

    使用最简单有效的设计。当你不需要使用AspectJ compiler/weaver 时,Spring AOP 比 完整的AspectJ 要简单有效。若你只需要增强beans里的方法,Spring AOP是个好的选择。若要增强不被IoC容器托管的对象时,或者需要增强更为复杂的连接点(field get 和 set连接点等),那就只能使用AspectJ。

    配置Spring AOP,可以使用@Aspect注解和XML。

    什么情况使用@AspectJ ,什么情况使用XML?

    两种方式各有优缺点。

    Spring AOP设计的一大原则是无侵入性。而XML的方式更具无侵入性,并且这种配置方式对于Spring使用者来说也是最熟悉的,AOP的实现类是纯粹的POJO对象,配置一个企业级应用这是一个很好的选择(当需要改变切入点表达式只需要在配置文件 中更改)。

    当然,XML的方式有两个缺点,

    (1) 此方式并没有在唯一的地方 概括需求的实现。这违反DRY原则,DRY原则提到系统内任何一个知识都应该被 唯一的,不含糊的,有权威性的呈现。使用XML的方式,需求的实现就被切分成两片,一片是AOP的实现类,一片是XML中的配置。而使用@AspectJ, @Aspect 切面概括了需求的实现。

   (2) XML形式的配置,略微受限,XML不能结合多个Pointcuts,必须分开声明,如下两种方式:

@Pointcut(execution(* get*()))
public void propertyAccess() {} 
@Pointcut(execution(org.xyz.Account+ *(..))
public void operationReturningAnAccount() {}
@Pointcut(propertyAccess() && operationReturningAnAccount())
public void accountPropertyAccess() {}
<aop:pointcut id="propertyAccess" expression="execution(* get*())"/>
<aop:pointcut id="operationReturningAnAccount" expression="execution(org.xyz.Account+ *(..))"/>

   @AspectJ方式支持更多的初始化方式,更丰富的切入点的组合。通过@AspectJ可以将一个切面设计成一个模块单元。并且@AspectJ能被 Spring AOP 和 AspectJ  识别,当我们需要AspectJ的能力去实现一些Spring AOP不能实现的功能时,集成AspectJ会很容易。

    Spring 团队还是更倾向于大家使用 @AspectJ的方式。

 

4. Spring AOP的原理

     AOP的核心在于创建目标对象的代理上,如下图:

173201_pPj5_267347.png

 

      后续会从 Spring AOP初始化,到代理对象创建,以及如何触发调用 这三个角度,结合源码分析Spring AOP中个人觉得重要的部分。

 

   

转载于:https://my.oschina.net/alextrz/blog/880766

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值