基本概念

  • oinpoint(连接点):就是方法
  • Pointcut(切入点):就是挖掉共性功能的方法
  • Advice(通知):就是共性功能,最终以一个方法的形式呈现
  • Aspect(切面):就是共性功能与挖的位置的对应关系
  • Target(目标对象):就是挖掉功能的方法对应的类产生的对象,这种对象是无法直接完成最终工作的
  • Weaving(织入):就是将挖掉的功能回填的动态过程
  • Proxy(代理):目标对象无法直接完成工作,需要对其进行功能回填,通过创建原始对象的代理对象实现
  • Introduction(引入/引介) :就是对原始对象无中生有的添加成员变量或成员方法

image.png
image.png
image.png

AOP配置

aop:config

  • 名称:aop:config
  • 归属:beans标签
  • 作用:设置AOP
  • 格式:

    1. <beans>
    2. <aop:config>
    3. ------
    4. </aop:config>
    5. </beans>

    aop:aspect

  • 名称:aop:aspect

  • 归属:aop:config标签
  • 作用:设置具体AOP通知的切入点
  • 基本属性:
    • ref:通知所在的bean的id
  • 格式:

    1. <aop:config>
    2. <aop:aspect ref="beanId">
    3. --------
    4. </aop:aspect>
    5. </aop:config>

    aop:pointcut

  • 名称:aop:pointcut

  • 归属:aop:config标签、aop:aspect标签
  • 作用:设置切入点
  • 基本属性:
    • id:识别切入点的名称
    • expression:切入点表达式
      • 表达式组成:
        • 关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)
      • 表达式关键字:
        • execution :匹配执行指定方法
        • args :匹配带有指定参数类型的方法
        • within :……
        • this :……
        • target :……
        • @within :……
        • @target :……
        • @args :……
        • @annotation :……
        • bean :……
        • reference pointcut :……
      • 表达式通配符:
          • :单个独立的任意符号
        • .. :多个连续的任意符号,常用语简化包名参数的书写
        • +:专用于匹配子类类型
  • 格式:

    1. <aop:config>
    2. <aop:pointcut id="pointcutId" expression="......"/>
    3. <aop:aspect>
    4. <aop:pointcut id = "pointcutId"/>
    5. </aop:aspect>
    6. </aop:config>

    aop:before

  • 名称:aop:befor

  • 归属:aop:aspect标签
  • 作用:设置前置通知

    1. <aop:aspect ref="adviceId">
    2. <aop:before method="methodName" pointcut="......"/>
    3. </aop:aspect>

    aop:after

  • 名称:aop:after

  • 归属:aop:aspect标签
  • 作用:设置后置通知

    1. <aop:aspect ref="adviceId">
    2. <aop:after method="methodName" pointcut="......"/>
    3. </aop:aspect>

    aop:after-returning

  • 名称:aop:after-returning

  • 归属:aop:aspect标签
  • 作用:设置返回后通知
  • 基本属性

    • method :在通知类中设置当前通知类别对应的方法
    • pointcut :设置当前通知对应的切入点表达式,与pointcut-ref属性冲突
    • pointcut-ref :设置当前通知对应的切入点id,与pointcut属性冲突
      1. <aop:aspect ref="adviceId">
      2. <aop:after-retruning method="methodName" pointcut="......."/>
      3. </aop:aspect>

      aop:after-throwing

  • 名称:aop:after-throwing

  • 归属:aop:aspect标签
  • 作用:设置抛出异常后通知

    1. <aop:aspect ref="adviceId">
    2. <aop:after-throwing method="methodName" pointcut="......">
    3. </aop:aspect>

    aop:around

  • 名称:aop:around

  • 归属:aop:aspect标签
  • 作用:设置环绕通知

    1. <aop:aspect ref="adviceId">
    2. <aop:around method="methodName" pointcut="……"/>
    3. </aop:aspect>
  • 环绕通知是在原始方法的前后添加功能,在环绕通知中,存在对原始方法的显式调用

    1. public Object around(ProceedingJoinPoint pjp) throws Throwable {
    2. Object ret = pjp.proceed();
    3. return ret;
    4. }

    环绕通知方法相关说明:

  • 方法须设定Object类型的返回值,否则会拦截原始方法的返回。如果原始方法返回值类型为void,通知方 也可以设定返回值类型为void,最终返回null

  • 方法需在第一个参数位置设定ProceedingJoinPoint对象,通过该对象调用proceed()方法,实现对原始方法的调用。如省略该参数,原始方法将无法执行
  • 使用proceed()方法调用原始方法时,因无法预知原始方法运行过程中是否会出现异常,强制抛出Throwable对象,封装原始方法中可能出现的异常信息

    通知获取参数的数据

    第一种:

  • 设定通知方法第一个参数为JoinPoint,通过该对象调用getArgs()方法,获取原始方法运行的参数数组

    1. public void before(JoinPoint jp) throws Throwable {
    2. Object[] args = jp.getArgs();
    3. }

    第二种:

  • 设定切入点表达式为通知方法传递参数(锁定通知变量名)

  • 原始方法

image.png
第三种情况:

  • 设定切入点表达式为通知方法传递参数(改变通知变量名的定义顺序)
  • 原始方法

image.png