首页 > 解决方案 > Spring Boot 2 After aspect 查找成功或失败

问题描述

我正在使用 Spring Boot 2 来创建微服务。我需要创建一个After方面来执行一些代码。

@Aspect
@Component
public class FinallyAspect {

    @Pointcut("@annotation(finallyEvent)")
    public void runFinallyMethod(FinallyEvent finallyEvent) {}

    @After("runFinallyMethod(FinallyEvent finallyEvent)")
    public void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable { 
       // ...
    }
}

是否可以进入内部finallyMethod是否发生异常或方法是否成功返回?我可以使用注释来做到这一点@AfterReturning@AfterThrowing但是如果有办法检查该方法是否以错误或成功结束,那么我可以在一个函数中检查它。

标签: javaspring-bootaopaspectjspring-aop

解决方案


After -advice无法访问该方法是成功返回还是异常返回。有替代品...

您可以使用最通用的一种建议,使用一种方法手动实现您想要的东西。建议您使用可以实现所需行为的最不强大的通知类型(source)。我不推荐这种方法,因为如果以错误的方式实现,它在异常处理方面很容易出错。例如,如果您将成功代码放在 try-block 中,则此成功代码引发的异常也会被用于failure-code的相同 catch-block 捕获。此外,您需要确保重新抛出异常并返回.joinPoint.proceed()

如果您想这样做,这就是如何正确执行此操作:

@Around(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public Object finallyMethod(ProceedingJoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
    final Object res;
    try {
        res = joinPoint.proceed();
    } catch (Throwable e) {
        // code in case of failure
        throw e;
    }
    // code in case of success
    return res;
}

b) 使用私有方法清洁解决方案

在这种情况下,我建议使用AfterReturning -advice 和AfterThrowing -advice,然后使用指示成功/错误的参数调用私有方法。这更具可读性,没有Around -advice 的缺点,但使用了更多代码。

需要一个布尔值 ( success)

@AfterReturning(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodReturning(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
    finallyMethod(joinPoint, finallyEvent, true);
}

@AfterThrowing(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodThrowing(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
    finallyMethod(joinPoint, finallyEvent, false);
}

private void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent, boolean success) throws Throwable {
    if (success) {
        // code in case of success
    } else {
        // code in case of failure
    }
}

Throwable是需要的

@AfterReturning(value = "runFinallyMethod(finallyEvent)", argNames = "joinPoint,finallyEvent")
public void finallyMethodReturning(JoinPoint joinPoint, FinallyEvent finallyEvent) throws Throwable {
    finallyMethod(joinPoint, finallyEvent, null);
}


@AfterThrowing(value = "runFinallyMethod(finallyEvent)", throwing = "t", argNames = "joinPoint,finallyEvent,t")
public void finallyMethodThrowing(JoinPoint joinPoint, FinallyEvent finallyEvent, Throwable t) throws Throwable {
    finallyMethod(joinPoint, finallyEvent, t);
}

private void finallyMethod(JoinPoint joinPoint, FinallyEvent finallyEvent, Throwable t) throws Throwable {
    if (t == null) {
        // code in case of success
    } else {
        // code in case of failure
    }
}

推荐阅读