SpringAOP中的JointPoint

1,268 阅读3分钟

Joint Point

JointPoint是程序运行过程中可识别的点,这个点可以用来作为AOP切入点。JointPoint对象则包含了和切入相关的很多信息。比如切入点的对象,方法,属性等。我们可以通过反射的方式获取这些点的状态和信息,用于追踪tracing和记录logging应用信息。

Pointcut

pointcut 是一种程序结构和规则,它用于选取join point并收集这些point的上下文信息。 pointcut通常包含了一系列的Joint Point,我们可以通过pointcut来同时操作jointpoint。单从概念上,可以把Pointcut当做jointpoint的集合。

JointPoint和ProceedingJoinPoint区别

JointPoint 通过JpointPoint对象可以获取到下面信息

    #返回目标对象,即被代理的对象
    Object getTarget();
    #返回切入点的参数
    Object[] getArgs();
    #返回切入点的Signature
    Signature getSignature();
    #返回切入的类型,比如method-call,field-get等等
    String getKind();

ProceedingJoinPoint

  Proceedingjoinpoint 继承了 JoinPoint。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法。 环绕通知=前置+目标方法执行+后置通知,proceed方法就是用于启动目标方法执行的

  暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,,这也是环绕通知和前置、后置通知方法的一个最大区别。这跟切面类型有关), 能决定是否走代理链还是走自己拦截的其他逻辑。建议看一下 JdkDynamicAopProxy的invoke方法,了解一下代理链的执行原理。

ps:ProceedingJoinPoint is only supported for around advice

JointPoint使用详解

  获取切入点的方法名字及其参数、切入点方法标注的注解对象(通过该对象可以获取注解信息)、 切入点目标对象(可以通过反射获取对象的类名,属性和方法名)
ps:有一点非常重要,Spring的AOP只能支持到方法级别的切入,即:切入点只能是某个方法。

1 获取切入点所在目标对象

    #获取目标对象
    Object targetObj =joinPoint.getTarget();

可以发挥反射的功能获取关于类的任何信息,例如获取类名如下

    #获取类的名字
    String className = joinPoint.getTarget().getClass().getName();

2.获取切入点方法的名字 getSignature());是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名

    #获取方法的名字
    String methodName = joinPoint.getSignature().getName()
  1. 获取方法上的注解 方法1:xxxxxx是注解名字
    Signature signature = joinPoint.getSignature();
    MethodSignature methodSignature = (MethodSignature) signature;
    Method method = methodSignature.getMethod();
    if (method != null){
        #获取注解
        xxxxxx annoObj= method.getAnnotation(xxxxxx.class);
    }
    return null;

方法2:上面我们已经知道了方法名和类的对象,通过反射可以获取类的内部任何信息。

    // 切面所在类
    Object target = joinPoint.getTarget();
    String methodName = joinPoint.getSignature().getName();
    Method method = null;
    for (Method m : target.getClass().getMethods()) {
        if (m.getName().equals(methodName)) {
            method = m;
            break;
        }
    }
  1. 获取方法的参数 这里返回的是切入点方法的参数列表
    Object[] args = joinPoint.getArgs();