spring之AOP

阅读更多
一、AOP术语
    Aspect(切面): aspect 由 pointcount 和 advice 组成, 它既包含了横切逻辑的定义,切面就是对横切关注点的抽象。
    pointcut(切点): 匹配 join point 的谓词(a predicate that matches join points)。
    advice(增强): 指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、最终、环绕通知五类。
    target(目标对象): 织入 advice 的目标对象. 目标对象也被称为 advised object。
    joinpoint(连接点): 程序运行中的一些时间点, 例如一个方法的执行, 或者是一个异常的处理。
    weave(织入): 将 aspect 和其他对象连接起来, 并创建 adviced object 的过程。也就是生成代理对象的过程。
    introduction(引入): 在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

    总结: Aspect,pointcut,advice是一个抽象的整体,AOP织入 advice 的目标对象生成一个代理对象,通过pointcut规则拦截target中的joinpoint,并执行advice的代码。pointcut是定义规则,joinpoint是具体的方法和异常。

二、Java注解实现AOP
   AspectJ切入点指示符如下:
         execution:用于匹配方法执行的连接点;
         within:用于匹配指定类型内的方法执行;
         this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
         target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
         args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
         @within:用于匹配所以持有指定注解类型内的方法;
         @target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
         @args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
         @annotation:用于匹配当前执行方法持有指定注解的方法;
         bean:Spring AOP扩展的,AspectJ没有对于指示符,用于匹配特定名称的Bean对象的执行方法;
         reference pointcut:表示引用其他命名切入点,只有@ApectJ风格支持,Schema风格不支持。

       AspectJ切入点支持的切入点指示符还有: call、get、set、preinitialization、staticinitialization、initialization、handler、adviceexecution、withincode、cflow、cflowbelow、if、@this、@withincode;但Spring AOP目前不支持这些指示符,使用这些指示符将抛出IllegalArgumentException异常。这些指示符Spring AOP可能会在以后进行扩展。

// 使用 Java Configuration 方式使能@AspectJ
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
}

//定义切面
@Aspect
public class NotVeryUsefulAspect {
  // 定义切点 匹配transfer方法
  @Pointcut("execution(* transfer(..))")// the pointcut expression
  private void anyOldTransfer() {}// the pointcut signature

  // 定义advice transfer方法前执行
  @Before("com.xyz.myapp.NotVeryUsefulAspect.anyOldTransfer()")
  public void doAccessCheck() {
    // ...
  }

  //合@Pointcut合@Before一体
  @Before("execution(* transfer(..))")
  public void doAccessCheck2() {
    // ...
  }
}

三、XML实现AOP




        
                

        
        
        
        
        
        
            
            
                
                
                
                
                
            
        



四、AOP代理

    AOP的源码中用到了两种动态代理来实现拦截切入功能: jdk动态代理cglib动态代理
    JDK动态代理:
  1. 通过实现InvocationHandlet接口创建自己的调用处理器
  2. 通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理
  3. 通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型
  4. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入

    JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,
Spring通过java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。


    CGLib动态代理
    CGLib是一个强大、高性能的Code生产类库,可以实现运行期动态扩展java类,Spring在运行期间通过 CGlib继承要被动态代理的类,重写父类的方法,实现AOP面向切面编程呢。

    比较:
  • JDK动态代理是面向接口,在创建代理实现类时比CGLib要快,创建代理速度快。
  • CGLib动态代理是通过字节码底层继承要代理类来实现(如果被代理类被final关键字所修饰,那么抱歉会失败),在创建代理这一块没有JDK动态代理快,但是运行速度比JDK动态代理要快。


        
        

        
        


参考资料: https://docs.spring.io/spring/docs/2.5.x/reference/aop.html#aop-using-aspectj

你可能感兴趣的:(AOP,代理,AOP,AspectJ,cglib,pointcut)