我有一个@Aspect
注释类正在调用ProceedingJoinPoint#proceed()
。
这个方法throws Throwable
,因此类看起来像这样:
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return joinPoint.proceed();
} finally {
//some more code here
}
}
}
myMehtod
是否可以在此方案中抛出Throwable
,我必须调用throws Throwable
的另一种方法?
我应该避免抛出Throwable
并以某种方式将其转换为Exception
或Error
吗?
在任何一种情况下,我都想知道原因。谢谢。
答案 0 :(得分:3)
不,扔掉Throwable是不行的。不应该捕获错误和未经检查的异常;错误是严重或致命的系统问题,而未经检查的异常(通常)会暴露程序员的错误。声明throws Throwable
的签名会强制调用者捕获并允许它们抑制不应被捕获或被抑制的东西。
如果可能的话,你应该修复ProceedingJoinPoint.proceed()
方法的签名,但是如果你无法控制那个类,你自己的代码应该把它包装在一个更合理的例外中。
如何包装它取决于您对代码调用者的期望。如果任何Throwable可能是一个条件,没有人可以做任何事情来纠正或解决,你可以将其包装在未经检查的RuntimeException中:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new RuntimeException(t);
} finally {
//some more code here
}
如果你想确保调用者优雅地处理所有Throwables,你应该创建自己的特定于应用程序的异常类:
try {
return joinPoint.proceed();
} catch (Throwable t) {
throw new JoinPointException(t);
} finally {
//some more code here
}
异常类只是:
public class JoinPointException
extends Exception {
private static final long serialVersionUID = 1;
public JoinPointException(Throwable cause) {
super(cause);
}
public JoinPointException(String message,
Throwable cause) {
super(message, cause);
}
}
答案 1 :(得分:0)
如果您使用Lombok,则可以使用@SneakyThrows来抛出Throwable而不声明它。
@Aspect
@Component
public class MyClass{
@Around("@annotation(myAnnotation)")
public Object myMethod(final ProceedingJoinPoint joinPoint) throws Throwable {
//some code here
try {
return proceed(joinPoint)
} finally {
//some more code here
}
}
@SneakyThrows
public Object proceed(ProceedingJoinPoint joinPoint) {
return joinPoint.proceed();
}
}
这是我所知避免捕获和包装Throwable或已检查异常的唯一方法。