是否可以针对给定异常类型的任何执行构建 @A​​fterThrowing 建议?

Is it possible to build a @AfterThrowing advice on any execution with a given exception type?

所以我有一个建议的工作示例,在抛出异常后应该 运行,上面有一个特定的注释。所以 ExtendedErrorHandling 是在 class and/or 方法上面使用的注解。当那个方法 returns 一个 ExtendedHttpResponseException 类型的特定错误时,建议应该 运行.

然而,最初的想法是不使用注释来实现这一点。

原样:

@AfterThrowing(pointcut = "execution(* *(..)) && (extendedThrowingInMethod() || extendedThrowingInClass())", throwing = "ex")

未来:

@AfterThrowing(pointcut = "execution(* *(..))", throwing = "ex")

当我们尝试实现此目的时,spring 拒绝启动,并显示一条非常通用的错误消息“tomcat 无法启动”,但也暗示建议不正确。

错误:

Caused by: org.springframework.boot.web.server.WebServerException: Unable to start embedded Tomcat
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:142)
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104)
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:473)
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:206)
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory$$FastClassBySpringCGLIB$c83fa9f.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:783)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:64)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:97)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:753)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:698)
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory$$EnhancerBySpringCGLIB$134ef1.getWebServer(<generated>)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160)
    ... 78 more
Caused by: java.lang.IllegalStateException: StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbeddedContext[] failed to start
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.rethrowDeferredStartupExceptions(TomcatWebServer.java:187)
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:126)
    ... 96 more

全方面:

@Aspect
@Component
public class ExtendedHttpResponseExceptionCatcherAdvisor {

@Pointcut("@annotation(com.atlascopco.common.dto.handlers.annotations.ExtendedErrorHandling)")
public void extendedThrowingInMethod() {

}

@Pointcut("@within(com.atlascopco.common.dto.handlers.annotations.ExtendedErrorHandling)")
public void extendedThrowingInClass() {

}

@AfterThrowing(pointcut = "execution(* *(..)) && (extendedThrowingInMethod() || extendedThrowingInClass())", throwing = "ex")
public void handleThrownKnownExceptions(ExtendedHttpResponseException ex) {
    ResponseContext responseContext = ResponseContextHolder.getResponseContext();
    GenericHttpResponseModel responseModel = responseContext.getResponseModel();
    responseModel.getErrors().add(ex);
    responseContext.setResponseModel(responseModel);
}

}

所以这里的问题是:为什么 spring 会在 TO-BE 情况下崩溃?是否有可能毫无问题地实现 TO-BE 情况,或者我们是否 运行 有一些限制?

提前感谢您的帮助!

感谢@R.G。

解决方案是在class定义时更具体。例如:

执行(* com.your.project..*(..))