深入理解AOP

5.AOP

  1. 静态AOP的优点是,Aspect直接以Java字节码的形式编译到Java类中,虚拟机可以像通常一样加载Java类允许,不会对整个系统的运行造成任何的性能损失。
  2. 动态AOP:AOP的各种概念实体全部都是普通的Java类,所以很容易开发和集成。AOP的织入过程在系统运行开始之后进行,而不是预先编译到系统类中,而且织入信息大都采用外部XML文件格式保存,可以在调整织入点以及织入逻辑单元的同时,不必变更系统其它模块。

1.Java上的AOP实现机制

  1. 动态代理:
    1、可以在运行期间,为相应的接口动态生成对应的代理对象。所以,我们可以将横切关注点逻辑封装到动态代理的InvocationHandler中,然后在系统运行期间,根据横切关注点需要织入的模块位置,将横切逻辑织入到相应的代理类中。
    2、所有需要织入横切关注点逻辑的模块类都得实现相应的接口。因为动态代理机制只针对接口有效
  2. 动态字节码增强:
    1、我们可以为需要织入横切逻辑的模块类在运行期间,通过动态字节码增强技术,为这些系统模块类生成相应的子类,而将横切逻辑加到这些子类中,让应用程序在执行期间使用的是这些动态生成的子类,从而达到将横切逻辑织入系统的目的。
    2、使用动态字节码增强技术,即使模块类没有实现相应的接口,我们依然可以对其进行扩展,而不用像动态代理那样受限于接口。不过,如果需要扩展的类以及类中的实例方法等声明为final的话,则无法对其进行子类化的扩展。
    3、Spring AOP在无法采用动态代理机制的时候,会使用CGLIB库的动态字节码增强支持来实现AOP的功能扩展。
  3. 自定义类加载器:
    1、我们可以通过自定义类加载器的方式完成横切逻辑到系统的织入,自定义类加载器通过读取外部文件规定的织入规则和必要信息,在加载class文件期间就可以将横切逻辑添加到系统模块类的现有逻辑中,然后将改动后的class交给虚拟机运行。
  4. AOL扩展:
    1、AOL扩展时最强大、也最难掌握的一种方式。在这种方式中,AOP的各种概念在AOL中大都有一一对应的实体。我们可以使用扩展过的AOL,实现任何AOP概念实体甚至OOP概念实体。

2.AOP国家的公民

  1. Joinpoint
    1、要进行织入过程,需要知道在系统的哪些执行点上进行织入操作,这些将要在其之上进行织入操作的系统执行点就称之为Joinpoint。
    2、方法调用是在调用对象上的执行点,而方法执行则是在被调用到的方法逻辑执行时的点。对于同一对象,方法调用要先于方法执行。
  2. Pointcut
    1、Pointcut概念代表的是Joinpoint的表述方式。将横切逻辑织入当前系统的过程中,需要参照Pointcut规定的Joinpoint信息,才可以知道应该往系统的哪些Joinpoint上织入横切逻辑。
    2、当前AOP产品所使用的Pointcut表达形式划分:
    (1)直接指定Joinpoint所在方法名称:表述方式比较简单,功能单一,通常只限于支持方法级别Joinpoint的AOP框架。
    (2)正则表达式:这是比较普遍的表达方式。
    (3)使用特定的Pointcut表述语言:最强大
    3、支持Pointcut运算
  3. Advice
    1、Advice是单一横切关注点逻辑的载体,它代表将会织入到Joinpoint的横切逻辑。
    2、按照Advice执行时机的差异或者完成功能的不同,可分为:
    (1)Before Advice:
    是在指定位置之前执行的Advice类型。通常,它不会中断程序执行流程,但如果必要,可以通过在Before Advice中抛出异常的方式来中断当前程序流程。
    (2)After Advice:
    After returning Advice 只有当前Joinpoint处执行流程正常完成后,才会执行。
    After throwing Advice 只有抛出异常情况下才执行
    After Advice 总是执行
    (3)Around Advice:
    可以在Joinpoint之前和之后都指定相应的逻辑,甚至于中断或者忽略Joinpoint处原来程序流程的执行
    (4)Introduction:
    1、它不是根据横切逻辑在Joinpoint处的执行时机来区分的,而是根据它可以完成的功能而区别于其他Advice类型
    2、它可以为原有的对象添加新的特性或行为。AspectJ采用静态织入的形式,那么对象在使用的时候,Introduction逻辑已经是编译织入完成的。
  4. Aspect
    1、Aspect是对系统中的横切关注点逻辑进行模块化封装的AOP概念实体。通常,Aspect可以包含多个Pointcut以及相关Advice定义。
    2、Spring AOP因为集成了AspectJ,所以可以通过使用@AspectJ的注解并结合普通的POJO来声明Aspect。
  5. 织入和织入器:
    Spring采用一组类来完成最终的织入操作,ProxyFactory类则是Spring AOP中最通用的植入器。
  6. 目标对象:
    1、符合Pointcut所指定的条件,将在织入过程中被织入横切逻辑的对象,称为目标对象。

6.Spring AOP概述及其实现机制

Spring AOP属于第二代AOP,采用动态代理机制和字节码生成技术实现。与最初的AspectJ采用编译器将横切逻辑织入目标对象不同,动态代理机制和字节码生成都是在运行期间为目标对象生成一个代理对象,而将横切逻辑织入到这个代理对象中,系统最终使用的是织入了横切逻辑的代理对象,而不是真正的目标对象。

1.设计模式之代理模式

  1. Proxy内部持有Impl的引用。当Client通过request()请求服务的时候,Proxy将转发该请求给Impl。不过。Proxy的作用不只局限于请求的转发,更多时候是对请求添加更多访问限制。
  2. 如果Impl是系统中Joinpoint所在的对象,那么就可以为这个目标对象创建一个代理对象,然后将横切逻辑添加到这个代理对象中。

2.动态代理

  1. 可以使用该机制,为指定的接口在系统运行期间动态地生成代理对象,从而帮助我们走出最初使用静态代理实现AOP的窘境。
  2. 即使有很多目标对象类型,只要它们织入的横切逻辑相同,用InvocationHandler的一个实现类并通过Proxy为它们生成相应的动态代理实例就可以满足要求。当Proxy动态生成的代理对象上相应的接口方法被调用时,对应的InvocationHandler就会拦截相应的方法调用,并进行相应处理。
  3. InvocationHandler就是实现横切逻辑的地方,它是横切逻辑的载体,作用跟Advice是一样的。
  4. 动态代理虽好,但不能满足所有的需求。因为动态代理机制只能对实现了相应Interface的类使用。
  5. 默认情况下,如果Spring AOP发现目标对象实现了相应Interface,则采用动态代理机制为其生成代理对象实例。而如果目标对象没有实现任何Interface,会尝试使用一个称为CGLIB(Code Generation Library)的动态字节码生成类库,为目标对象生成动态的代理对象实例。

3.动态字节码生成

  1. 使用动态字节码生成技术扩展对象行为的原理是,我们可以对目标对象进行继承扩展,为其生成相应的子类,而子类可以通过重写来扩展父类的行为,只要将横切逻辑的实现放到子类中,然后让系统使用扩展后的目标对象的子类,就可以达到与代理模式相同的效果了。
  2. 不论是否实现了接口,CGLIB都可以对其进行扩展。
  3. 通过为enhancer指定需要生成的子类对应的父类,以及Callback实现,enhancer最终为我们生成了需要的代理对象实例。

7.Spring AOP中的Joinpoint

1.Joinpoint

  1. SpringAOP仅支持方法执行的Joinpoint。

2.Pointcut

  1. Pointcut接口定义了2个方法用来帮助捕捉系统中相应的Joinpoint,并提供了一个TruePointcut类型实例。如果Pointcut类型为TruePointcut,默认会对系统中的所有对象,以及对象上所有被支持的Joinpoint进行匹配。
  2. ClassFilter和MethodMatcher分别用于匹配将被执行织入操作的对象以及相应的方法。之所以分开定义,是因为可以重用不同级别的匹配定义,并且可以在不同的级别或相同的级别上进行组合操作,或强制让某个子类只重写相应的方法定义等。
  3. MethodMatcher通过重载,定义了2个matches方法。在对对象具体方法进行拦截的时候,可以忽略每次方法执行的时候传入的参数,也可以检查。
  4. 当isRuntime返回false时,表示不会考虑具体Joinpoint的方法参数,这种类型的MethodMatcher称之为StaticMethodMatcher;反之,每次都对参数进行匹配检查,这种称之为DynamicMethodMatcher。(尽量避免) PS:会优先执行StaticMethodMatcher,如果返回false,表示该结果已是最终匹配结果。DynamicMethodMatcher就不会执行。
  5. Spring中的Pointcut实现都是普通的Java对象,所以,同样可以通过Spring的IOC容器来注册并使用他们。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值