如何解决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 无法访问方法是成功返回还是出现异常。还有其他选择...
a) Around-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 举报,一经查实,本站将立刻删除。