Bootstrap

AOP中ProceedingJoinPoint用法

ProceedingJoinPoint 是 AOP(面向切面编程)编程中的一个重要概念,特别是在 Spring AOP 中。它代表了方法调用的“执行点”,通常在方法调用之前或之后插入额外的逻辑。ProceedingJoinPoint 提供了对方法调用的控制,允许你决定是否继续执行原始方法、如何执行或完全不执行。

以下是 ProceedingJoinPoint 的主要方法和它们的作用:

getSignature()

  • 描述:获取方法的签名(例如,方法名和参数类型)。

//获取切入点所有信息(签名)
MethodSignature signature = (MethodSignature) point.getSignature();
//获取该注解标注的方法入参名
String[] paramNames = signature.getParameterNames();
//获取切入点方法对象
Method method = signature.getMethod();
//获取目标方法参数个数
int parameterCount = method.getParameterCount();
​
例如:
  @DoubleCache(
            value = "user2",
            key = "'primary_key' + #user.userId",
            type = CacheType.FULL
    )
    public User2 queryByPrimaryKey(User2 userParam){
        User2 user2 = new User2();
        user2.setUserId(user.getUserId());
        return user2Mapper.selectByPrimaryKey(user2);
    }
示例:
  String[] paramNames = signature.getParameterNames();
  paramNames:[userParam]
示例:
  int parameterCount = method.getParameterCount();
  parameterCount:1
//获取注解
DoubleCache annotation = method.getAnnotation(DoubleCache.class);

getArgs()

  • 描述:获取传递给方法的参数。

  • 用途:你可以获取原始方法的参数,这在需要对参数进行操作或修改时非常有用。

  • 示例:你可能想在方法调用之前修改某些参数的值。

//获取该方法的入参值
Object[] args = point.getArgs();
例如:
  @DoubleCache(
            value = "user2",
            key = "'primary_key' + #user.userId",
            type = CacheType.FULL
    )
    public User2 queryByPrimaryKey(User2 userParam){
        User2 user2 = new User2();
        user2.setUserId(user.getUserId());
        return user2Mapper.selectByPrimaryKey(user2);
    }
示例:
  Object[] args = point.getArgs();
  args:User2(userId=3, userName=王五, createTime=null)

proceed()

  • 描述:继续执行原始方法。

  • 用途:在 around advice 中,你可以决定是否继续执行原始方法。

  • 示例:如果你要在方法调用之前和之后插入日志,你可以先调用 proceed(),然后记录日志,最后返回原始方法的返回值。

//获取原来的方法被执行的结果,执行到这个地方的时候会去先执行被代理的方法拿到其执行结果
Object object = point.proceed();

getThis()

  • 描述:获取代理对象(即当前对象)。

  • 用途:在某些情况下,你可能需要访问代理对象本身,而不是其中的方法。

getTarget()

  • 描述:获取被代理的对象(即实际对象)。

  • 用途:与 getThis() 相对,它允许你访问实际对象而不是代理对象。

getKind()

  • 描述:获取连接点的类型(例如,它是一个方法连接点还是一个构造函数连接点)。

  1. proceedingJoinPoint.toLong()proceedingJoinPoint.toShort() 等其他类型转换方法

    • 描述:这些方法将连接点转换为特定的 Java 数据类型(例如 long, short 等)。

    • 用途:通常在执行数学运算或其他特定类型操作时使用。

  2. proceedingJoinPoint.getFileName()proceedingJoinPoint.getLineNumber() 等其他关于源代码位置的方法

    • 描述:这些方法提供关于连接点在源代码中的位置的信息。

    • 用途:在调试或记录日志时非常有用,可以知道问题发生的位置。

  3. proceedingJoinPoint.setRemove监听(boolean) 等其他方法

  • 这些方法是 ProceedingJoinPoint 的特定扩展,允许你修改其行为或添加额外的功能。它们不是标准的 AOP 方法,但可能在某些库或框架中使用。

@Around("pointcut()")
public Object afterMonitor(ProceedingJoinPoint point) throws Throwable {

    Object proceed = point.proceed();
    MethodSignature signature = (MethodSignature)point.getSignature();
    Method method = signature.getMethod();
    int parameterCount = method.getParameterCount();
    Object[] args = point.getArgs();
    if (proceed instanceof User){
        LocalDateTime createTime = ((User) proceed).getCreateTime();
        if(createTime.getDayOfMonth()==6){
            for (int i = 0; i < parameterCount; i++) {
                if (args[i] instanceof Object){
                    Object strategy = (Object)args[i];
                    ......
                }
            }
        }

    }
    return proceed;
}

;