java - 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
但是如果有办法检查该方法是否以错误或成功结束,那么我可以在一个函数中检查它。
解决方案
After -advice无法访问该方法是成功返回还是异常返回。有替代品...
a) around -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
}
}
推荐阅读
- rspec - Net :: ReadTimeout 发生在 Rails SystemTest 中
- html - 为什么我的 CSS 在放入 div 时只影响 IMG?
- php - XDebug 仅适用于 localhost 而不是远程主机
- sql - 大数据集的中位数,之前可以聚合吗?
- java - Maven 项目继承:无法解析来自父项目的导入
- python - 如何根据多个属性对列表项进行排序,而最后一个优先级是字母?
- javascript - 是否可以用线条或不是矩形的画布制作带有背景的画布?
- python-3.x - 为什么在 python 中使用求和方程只显示 0 个值
- c# - DateTime.ToString(String, IFormatProvider) 不适用于 Xamarin.Forms 中的波斯文 CultureInfo“fa-IR”
- java - Java中使用DAO模式的多对多关系