Spring AOP AfterThrowing 与 around Advice
当尝试实现一个负责捕获和记录某种类型错误的方面时,我最初认为使用 AfterThrowing 建议可以实现这一点。然而,他的建议似乎没有捕获异常,而只是提供了一个额外的入口点来对异常执行某些操作。
唯一能够捕获有问题的异常的建议是 aroundAdvice - 要么是我做错了什么。
任何人都可以断言,如果我想捕获异常,我确实必须使用 aroundAdvice 吗?我使用的配置如下:
@Pointcut("execution(* test.simple.OtherService.print*(..))")
public void printOperation() {}
@AfterThrowing(pointcut="printOperation()", throwing="exception")
public void logException(Throwable exception) {
System.out.println(exception.getMessage());
}
@Around("printOperation()")
public void swallowException(ProceedingJoinPoint pjp) throws Throwable {
try {
pjp.proceed();
} catch (Throwable exception) {
System.out.println(exception.getMessage());
}
}
请注意,在这个示例中我捕获了所有异常,因为它只是一个示例。我知道吞掉所有异常是不好的做法,但对于我当前的用例,我希望只记录一种特殊类型的异常,同时避免重复的日志记录逻辑。
when trying to implement an Aspect, that is responsible for catching and logging a certain type of error, I initially thought this would be possible using the AfterThrowing advice. However it seems that his advice doesn't catch the exception, but just provides an additional entry point to do something with the exception.
The only advice which would also catch the exception in question would then be an AroundAdvice - either that or I did something wrong.
Can anyone assert that indeed if I want to catch the exception I have to use an AroundAdvice? The configuration I used follows:
@Pointcut("execution(* test.simple.OtherService.print*(..))")
public void printOperation() {}
@AfterThrowing(pointcut="printOperation()", throwing="exception")
public void logException(Throwable exception) {
System.out.println(exception.getMessage());
}
@Around("printOperation()")
public void swallowException(ProceedingJoinPoint pjp) throws Throwable {
try {
pjp.proceed();
} catch (Throwable exception) {
System.out.println(exception.getMessage());
}
}
Note that in this example I caught all Exceptions, because it just is an example. I know its bad practice to just swallow all exceptions, but for my current use case I want one special type of exception to be just logged while avoiding duplicate logging logic.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
Spring 参考医生说:
到那时捕获异常已经太晚了,因为它已经被抛出并且方法已经退出。您使用 @Around 建议采取的方法是实际捕获异常并在之前处理它的唯一方法该方法退出。
The Spring reference doc says:
By then it's too late to catch the exception as it has already been thrown and the method has exited. The approach you've taken with the @Around advice is the only way to actually catch the exception and deal with it before the method exits.
实际上,也可以在 AfterThrowing 建议中捕获异常。
我知道这是一个复杂的例子,但它确实有效。
正如您所看到的,更多的是关于如何捕获最初抛出的异常,从而防止其传播回调用者。
GitHub 上的工作示例(检查 com.example.advices 包)
Actually, it is possible to catch exception within AfterThrowing advice as well.
I know it is a convoluted example, but it works.
As you can see it is more about how to catch originally thrown exception and thus prevent its propagation back to the caller.
Working example on GitHub (check com.example.advices package)