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

2024-03-11

我有一个自定义记录器使用@Aspect我希望它总是最后运行,这样无论控制器返回什么响应,它都会被记录到数据库中(所以我放了一个@Order(1)在这方面)。我还使用编写了一个错误处理程序@ControllerAdvice处理所有意外异常并返回500使用自定义响应正文,我也希望记录器记录它,所以我放了一个@Order(2)但看起来像是把@Order注解不会安排 Spring Aspect 和 Spring ControllerAdvice 之间的顺序,那么如何让我的错误处理程序始终在记录器之前运行? (当然,无需将我的错误处理程序转换为另一个 Spring Aspect)


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

您是否考虑过使用Interceptor?

它们提供了在进入控制器之前和之后记录操作的方法@ControllerAdvice被执行,如果有的话。

@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");
    }
}

我创建了一个简单的Controller and ControllerAdvice对于测试:

@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");
    }
}

结果是:

WebAdvice 句柄现已记录
WebInterceptor 完成后现在已记录

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

这是我发现的有关 Order、Aspect 和 ControllerAdvice 的内容

你是对的,之间没有优先级@ControllerAdvice and a @Aspect,嗯,有点……

我不知道为什么(还没有),但是当@Aspect在指向一个@Controller方法,那么切点将在@ControllerAdvice,无论您设置的顺序如何

@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");
    }
}

If you Get http://localhost:8080/user结果将是:

方面现已记录
ControllerAdvice 现已记录

但我发现了一些有趣的事情:如果你设置了切入点@After the @ControllerAdvice那么你可以在controllerAdvice之后执行方面:

@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次。一份在控制器之后,一份在建议之后。

方面现已记录
ControllerAdvice 现已记录
方面现已记录

也许这可以满足您的需求,但我真的不认为这是一个优雅的解决方案......

还需要解决的事情:

  • 找到一种方法来获得优先权Aspect and ControllerAdvice

无论如何希望它有帮助。如果我找到更好的东西,我会告诉你。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何让 Spring @ControllerAdvice 与其他自定义 Spring @Aspect 一起工作? 的相关文章

随机推荐

  • 为 Django 模型生成非序列 ID/PK

    我即将开始开发新的网络应用程序 其中一部分将为用户提供可以以一对多关系进行自定义的页面 这些页面自然需要有唯一的 URL 留给自己的设备 Django 通常会分配一个标准AUTOINCREMENT模型的 ID 虽然这效果非常好 但看起来不太
  • 从整数流创建平衡二叉搜索树

    我刚刚结束了一次工作面试 我一直在纠结这个问题 在我看来 在 15 分钟的面试中这是一个很难回答的问题 问题是 编写一个函数 给定整数流 无序 构建平衡搜索树 现在 您不能等待输入结束 它是一个流 因此您需要动态平衡树 我的第一个答案是使用
  • 城市和经纬度距离

    我有一张桌子 城市 纬度 经度 我需要一个 sql 查询来了解所有城市距离纽约 100 英里 这是我们的 您可能需要根据您的表结构修改它 我们查找零售地点 和便利设施 而不是城市 但困难的部分是本声明中起作用的 距离最近 CREATE PR
  • python2.5 virtualenv 中的 MySQLdb

    我有一个带有 MySQL 服务器的 Fedora 11 机器 Fedora 11 内部使用 python 2 6 并且 python 2 6 会自动安装在盒子上 我已经为 2 5 5 版本创建了一个 python virtual env 以
  • MySQL max_allowed_pa​​cket 重置

    由于某些超出我所知的原因 我几乎每天都必须重置 max allowed pa cket 有时甚至一天多次 SET GLOBAL max allowed packet 1073741824 我已经沿着这些思路搜索了 MySql bug 的报告
  • CSS 将边框应用于云形状?

    我通过 CSS3 使用不同的方式画了一朵云div我正在尝试为整个形状添加边框 但我遇到了麻烦 因为每个形状都有自己的边框 如何将边框应用于整个云 HTML div div div div div div div div CSS margin
  • Vim 复制行号?

    我通过 SSH 连接使用 vim 我已经设置了数字设置 因此当我尝试用鼠标复制代码部分时 它也会抓取数字 有没有一种复制文本而不抓取数字的好方法 我知道在那个 vim 实例中我可以使用 Y 但我需要一种复制到其他实例和程序的方法 这是我正在
  • OSGI 嵌套依赖 jar

    如果我有一个 OSGI Bundle 其中包含嵌套在 OSGI Bundle jar 中的依赖项 jar 我是否需要在 Import Package 清单中列出这些类以便我可以使用它们 我认为不会 另外 如何将这些依赖项 jar 添加到我的
  • 通过 JDBC 瘦驱动程序连接 Oracle 11g 时出现问题 (Domino Java)

    我无法使用以下代码远程连接 Oracle 11 数据库 但是 如果我尝试连接安装在我的计算机上的 Oracle 9 数据库 相同的代码可以正常工作 缺什么 我没有收到任何错误 Lotus Notes 挂起 import lotus domi
  • 如何使用C++获取文件夹/目录名称,而不是一个文件的路径?特别是 boost::filesystem; [复制]

    这个问题在这里已经有答案了 std string file C folder1 folder2 folder3 txt fs path file path file fs path file dir file path parent pat
  • 成员初始值设定项列表是构造函数的声明或定义的一部分吗?

    请解释如何使用成员初始值设定项列表 我有一个类声明在 h文件和一个 cpp像这样的文件 class Example private int m top const int m size public Example int size int
  • 提高 SQL Server 对大型表的查询性能

    我有一个相对较大的表 当前有 200 万条记录 想知道是否可以提高即席查询的性能 这个单词ad hoc在这里是关键 添加索引不是一个选项 最常查询的列上已经有索引 运行一个简单的查询以返回 100 条最近更新的记录 select top 1
  • 了解 do-while 循环

    我正在做 Oracle 认证助理 Java SE7 程序员练习考试 书本 并遇到一个问题 即使有解释我也不明白答案 这是解释和代码 它将打印 3 循环体执行两次 程序将打印 3 我不明白循环体是如何执行两次的 也许我不明白什么是b b方法
  • JsonPath 与 Newtonsoft.JSON

    我尝试了近一个小时的不同方法 但我不明白 我的 JSON 对象是这样的 typeOfHair value code Dry Hair values value DryHair language en value TrockenesHaar
  • 为什么过滤未排序的列表比过滤排序的列表更快

    我一直在玩 Java 8Streams API我决定进行微基准测试stream and parallelStream 溪流 正如预期的那样parallelStream 速度是原来的两倍 但是会出现其他问题 如果我在将数据传递到之前对数据进行
  • 不使用
    标签是否可以实现类似
    的效果?

    我个人喜欢 fieldset http www w3 org wiki HTML Elements fieldset标签 因为它如何绘制一个盒子并放置 legend http www w3 org wiki HTML Elements le
  • django 中的竞争条件

    下面是一个带有潜在竞争条件的 django 视图的简单示例 myapp views py from django contrib auth models import User from my libs import calculate p
  • 重载方法调用重新设计

    我有一个界面IAction它有一个通用方法 public interface IAction void doAction ISignal sig IState state 另一堂课IActionAbstract然后实现IAction接口并调
  • 如何从 SugarCRM 的表中检索所有记录?

    我正在使用 Sugar Pro 6 1 想知道如何从产品表中检索所有产品及其 id 我正在尝试使用以下代码 sql SELECT id name FROM products order by name result GLOBALS db g
  • 如何让 Spring @ControllerAdvice 与其他自定义 Spring @Aspect 一起工作?

    我有一个自定义记录器使用 Aspect我希望它总是最后运行 这样无论控制器返回什么响应 它都会被记录到数据库中 所以我放了一个 Order 1 在这方面 我还使用编写了一个错误处理程序 ControllerAdvice处理所有意外异常并返回