当前位置: 首页 > 知识库问答 >
问题:

如何让Spring@ControllerAdvice与其他自定义Spring@Aspect一起工作?

陈阳舒
2023-03-14

我有一个使用@aspect的自定义记录器,我希望它总是在最后一次运行,这样无论控制器返回什么响应,它都将被记录到数据库中(所以我在这个方面放了一个@order(1))。我还使用@controllerAdvise编写了一个错误处理程序,它处理所有意外的异常并返回500,并带有自定义响应体,我希望日志记录器也记录它,因此我在它上添加了@order(2),但是看起来@order注释并没有在Spring方面和Spring ControllerAdvision之间安排顺序,那么如何让错误处理程序始终在日志记录器之前运行呢?(当然,没有将我的错误处理程序转到另一个Spring方面)

共有1个答案

申屠项明
2023-03-14

我一直在寻找和调试你的主要问题。我没有找到您关于@order的问题的答案,但我将与您分享我的想法(本文第二部分)

它们提供了在进入控制器之前以及在执行@controllerAdvise(如果有的话)之后记录操作的方法。

@Component
public class WebInterceptor extends HandlerInterceptorAdapter {

    private Logger logger = LoggerFactory.getLogger(WebInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.error("WebInterceptor prehandle is now logged");
        return super.preHandle(request, response, handler);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.error("WebInterceptor after completion is now logged");
        super.afterCompletion(request, response, handler, ex);
    }
}

要激活这个拦截器,您需要创建一个新的@configuration类,实现WebMVCConfigurer:

@Configuration
public class AppConfig implements WebMvcConfigurer {

    @Autowired
    private WebInterceptor webInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webInterceptor).addPathPatterns("/user");
    }
}
@RestController
public class WebController {
    @GetMapping("/user")
    public String user() {
        throw new IllegalArgumentException("my bad");
    }
}


@RestControllerAdvice
@Order(2)
public class WebAdvice {

    private Logger logger = LoggerFactory.getLogger(WebAdvice.class);

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void handle(RuntimeException e) {
        logger.error("ControllerAdvice is now logged");
    }
}

WebAdvision句柄现在被记录
现在记录完成后的WebInterceptor

如果需要记录请求,还可以查看以下内容:https://www.baeldung.com/spring-http-logging

你是对的,在@controllerAdvise@aspect之间没有优先级,嗯...

@Aspect
@Component
@Order(1)
public class MyAspect {

    private Logger logger = LoggerFactory.getLogger(MyAspect.class);

    @After("execution(* WebController.user(..))")
    public void afterLog() {
        logger.error("Aspect is now logged");
    }
}

@RestControllerAdvice
@Order(2)
public class WebAdvice {

    private Logger logger = LoggerFactory.getLogger(WebAdvice.class);

    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public void handle(RuntimeException e) {
        logger.error("ControllerAdvice is now logged");
    }
}

方面现在被记录
ControllerAdvision现在被记录

但是我发现了一些有趣的事情:如果在之后@controllerAdvise设置一个切入点@,那么在controllerAdvise之后将执行一个方面:

@Aspect
@Component
@Order(1)
public class MyAspect {

    private Logger logger = LoggerFactory.getLogger(MyAspect.class);

    @After("execution(* WebAdvice.handle(..)) || execution(* WebController.user(..))")
    public void afterLog() {
        logger.error("Aspect is now logged");
    }
}

执行2次。一个在控制器之后,一个在建议之后。

  • 寻找优先于aspectControllerAdvise
  • 的方法

希望能有所帮助。如果我找到更好的,我会告诉你的。

 类似资料:
  • pom.xml版本信息: SpringFox-Swagger2:2.5.0 昂首阔步-核心:1.5.10 springfox-swagger-ui:2.6.1 Springboot:1.5.3 我有一个项目与swagger2和Springboot。 没有@Aspect的项目代码工作得很好。 正确的结果: 但是当我添加以下代码时,swagger-ui没有显示test-api-impl。 swagge

  • 我有一个简单的过滤器,用于检查请求是否包含一个带有静态密钥的特殊头(无用户身份验证),以保护endpoint。这个想法是,如果键不匹配,抛出一个,然后映射到带有注释的类的响应。但是我不能让它工作。我的未被调用。 客户端 访问禁止例外 例外控制器 我错在哪里了?简单的servlet过滤器可以与Spring Boot的异常映射一起工作吗?

  • 我正在将我的Spring应用程序从Spring-boot 1.5.9迁移到Spring-boot 2.0.0。使用这个新的Spring包,我在Redis中缓存数据时遇到了一些问题。 在我的配置中,我有3个具有不同TTL(长、中、短)的CacheManager: 我还有一个自定义RestTemplate: 在上一个Spring版本中,缓存的每个数据都使用这个RestTemplate,并使用Gener

  • 在Spring Boot1.5.3中,我的@ControllerAdvice注释了ExceptionHandler有一个特殊的情况。它捕获任何异常默认异常,但如果我抛出一个自定义异常,它不会激发。 ExceptionHandler: 最上面的3个异常都被捕获并按预期处理,但最下面的异常由默认的Spring-Boot ExceptionHandler处理。这是我在控制器内部抛出的自定义异常: 我试着

  • 我正在编写一个Web项目,它使用了Apache Tomcat 5.0和JDK 1.4.2之上的Spring框架2.5。 当Tomcat启动时,它从未加载Spring。 Web.xml如下: "web-Application ationContext.xml"就像: 控制台提供了以下日志堆栈跟踪: 严重:配置类org的应用程序侦听器时出错。springframework。网状物上下文ContextL