微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot 2 在方面找到成功或失败后 a) Around-advice不推荐b) 使用私有方法清理解决方案

如何解决Spring Boot 2 在方面找到成功或失败后 a) Around-advice不推荐b) 使用私有方法清理解决方案

我正在使用 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 注释来完成,但如果有办法检查该方法是否以错误或成功结束,那么我可以在单个函数中检查它。

解决方法

使用After-advice 无法访问方法是成功返回还是出现异常。还有其他选择...

您想要的可以手动使用Around-advice(最通用的一种建议)通过单一方法实现。建议您使用可以实现所需行为的最不强大的通知类型 (source)。我不推荐这种方法,因为如果以错误的方式实现,它在异常处理方面可能容易出错。例如,如果您将 success-code 放在 try-block 中,则此 success-code 抛出的异常也会被与用于故障代码。此外,您需要确保重新抛出异常并返回 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)",finallyEvent")
public void finallyMethodReturning(JoinPoint joinPoint,FinallyEvent finallyEvent) throws Throwable {
    finallyMethod(joinPoint,finallyEvent,true);
}

@AfterThrowing(value = "runFinallyMethod(finallyEvent)",finallyEvent")
public void finallyMethodThrowing(JoinPoint joinPoint,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)",null);
}


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

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

我认为您无法使用 @After 来实现这一点,因为此注释只能在上下文中为您提供 JoinPoint,它没有关于返回值的信息。

如果您想在同一个方法中处理所有事情,我认为唯一的选择是使用 @Around 来实现它,您可以在方法执行前后做一些事情。您的实施可能是:

@Around("runFinallyMethod(FinallyEvent finallyEvent)")
public Object finallyMethod(ProceedingJoinPoint jp,FinallyEvent finallyEvent) throws Throwable { 
   try {
     Object result = jp.proceed();
     // do nice stuff with result
     return result;
   } catch(Throwable throwable) {
     // do nice stuff with the exception;
     throw throwable;
   }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?