joinPoint.proceed() 是做什么的?

What does joinPoint.proceed() do?

这是我第一次接触AOP。我有一个 spring-boot 应用程序,它有一个方面,一个 Logger。搜索我得出的结论是 @Around 方法在该方法之前和之后执行(我只在一个方法中调用它),这是对的吗? 在我的@Around 方法中间有一个 joinPoint.proceed()。如果我没记错的话,JoinPoint 是我必须用来获取调用方面的方法的信息的对象,但我无法理解进程实际在做什么!

这是我的代码:

@Around(value = "execution(* *(..)) && @annotation(Loggable)", argNames = "ProceedingJoinPoint, Loggable")
public Object logAround(ProceedingJoinPoint joinPoint, Loggable loggable) throws Throwable {

    String methodArguments = loggable.printMethodArguments() ? Arrays.toString(joinPoint.getArgs()) : "[]";

    long start = System.currentTimeMillis();
    Object returnObject = joinPoint.proceed(); // continue on the
                                                // intercepted method
    long elapsedTime = System.currentTimeMillis() - start;

    String returnValue = loggable.printReturn() && returnObject != null ? returnObject.toString() : "[]";

    LOG.info("Logging method: {}.{} Method arguments: {}. Method return value: {}. Method execution time: {}",
            joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName(), methodArguments,
            returnValue, elapsedTime);
    return returnObject;
}

正如您所提到的,@Around 建议围绕着一个连接点,例如方法调用。它可以在方法调用前后执行自定义行为。它还负责选择是继续到连接点还是缩短建议的方法执行。

在您的情况下,实际的方法调用(那些包含非常有用的业务逻辑的方法!)发生是因为 joinPoint.proceed();

正如您所说,当您使用 @Around 时,就像您可以在 方法之前做任何您想做的事,然后 invoke方法,调用完方法后就可以做任何想做的事情了。

//Read file, Log , .... (Before method calling)
//Invoke the method (joinPoint.proceed)
//Write to the file, complete log, .... (After method calling)

调用阶段由joinPoint.proceed()完成。


日志示例

1-调用方法前记录

2- 调用或调用您在其上设置切入点的方法 (proceed)

3-将日志存入数据库或写入文件或发送,...

授权示例

在这个示例中,使用@Around,您可以授权用户并确定他们是否可以使用该方法?

所以在方法调用之前需要做授权处理,如果授权是true然后调用方法如果不是抛出异常或者你可以登录。

1- 在调用方法之前授权用户

2- 如果授权是 true 那么 调用 方法 (joinPoint.proceed();)


综上所述joinPoint.proceed();表示调用set方法,或者调用中

@Around("someMethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("around - before - " + joinPoint.getSignature());
        try {
            System.out.println("Inside Try block of around");
            return joinPoint.proceed();
        } finally {
            System.out.println("around - after - " + joinPoint.getSignature());
        }
    }

    @Before("someMethod()")
    public void before(JoinPoint joinPoint) {
        System.out.println("before - " + joinPoint.getSignature());
    }

/*Consider above methods are matched to a pointcut for some joinpoint. If we didn't
use joinPoint.proceed() in @Around advice then @Before advice will not be called. 

Output with joinPoint.proceed()

  -around - before - " + joinPoint.getSignature()
  -"Inside Try block of around";
  -"before - " + joinPoint.getSignature()
  -around - after - " + joinPoint.getSignature()

Output without joinPoint.proceed()

   -around - before - " + joinPoint.getSignature()
   -"Inside Try block of around";
  -around - after - " + joinPoint.getSignature()
*/