AOP应用以及原理

0. AOP是什么?
AOP,面向切面编程,是对OOP的补充。面向切面编程有好几种方式,可以在编译时候织入,也可以在运行时候织入,将代码切入到指定的方法或者位置上去。一般来说有以下几种方式:
AspectJ编译时增强 aspectj编译时增强,既是静态代理增强,也就是会在编译阶段生成代理,将代码织入到Java的字节码中去。
Spring AOP的运行时增强 Spring AOP是基于代理机制的,并且Spring AOP使用的是动态代理增强,动态代理不会改变类的字节码,而是动态的生成代理对象。Spring AOP的动态代理机制有两种方式:JDK动态代理和CGLIB动态代理。
JDK动态代理 JDK动态代理需要被代理的类必须实现一个接口,通过使用反射来接受被代理的类。
CGLIB动态代理 CGLIB动态代理可以不用需要被代理类必须实现接口,被代理类可以是一个类。
Spring AOP 上面说到了Spring AOP中使用的是动态代理机制,同时也分为两种代理机制:JDK动态代理和CGLIB动态代理,这可以在源码中看到,在DefaultAopProxyFactory的createAopProxy中可看到:

public AopProxy createAopProxy(AdvisedSupport advisedSupport) throws AopConfigException { //可以看到这里有条件是没有实现接口 boolean useCglib = advisedSupport.getOptimize() || advisedSupport.getProxyTargetClass() || advisedSupport.getProxiedInterfaces().length == 0; if (useCglib) { return CglibProxyFactory.createCglibProxy(advisedSupport); } else { // Depends on whether we have expose proxy or frozen or static ts return new JdkDynamicAopProxy(advisedSupport); } }

对于接口的代理使用的JDK动态代理,而对于类的代理使用的是CGLIB动态代理。
AOP的相关概念
1. AOP的相关概念
  • Aspect,切面,一个关注点的模块化,这个关注点可能会横切多个对象。
  • JoinPoint(连接点),程序中可能作为代码注入目标的特定的点。在AspectJ中可以作为JoinPoints的地方包括:
JoinPoints 说明 示例
method call 函数调用 比如调用Log.e(),这是一处Joint point
method execution 函数执行 比如Log.e()的执行内部,是一处Joint Point
constructor call 构造函数调用 与方法的调用类型
constructor executor 构造函数执行 与方法的执行执行
field get 获取某个变量
field set 设置某个变量
static initialization 类初始化
initialization object在构造函数中做的一些工作
handler 异常处理 对应try-catch()中,对应的catch块内的执行
  • Advice,通知类型,在切面的某个特定的连接点上执行的动作。其实就是注入到class文件中的代码片。典型的 Advice 类型有 before、after 和 around,分别表示在目标方法执行之前、执行后和完全替代目标方法执行的代码:
    前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
    后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
    异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
    最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
    环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
  • Pointcut,切点,匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。
  • 【AOP应用以及原理】Weaving,注入代码(advices)到目标位置(joint points)的过程

    推荐阅读