You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取处理当前请求的端点方法引用(非当前方法)

获取Spring MVC中处理请求的控制器方法引用

问题描述

我有如下控制器类:

@RestController
public class Controller {
    @GetMapping("endpoint")
    public void endpoint() { }
}

我需要获取处理当前请求的方法引用(即Controller#endpoint()),注意并非在当前方法内部获取,而是处于过滤器或服务类这类场景中。最终目标是在自定义Spring Security栈里判断目标方法上是否存在@SomeRelevantAnnotation,不过这部分超出本次问题范围。

我目前想到的方案是:通过RequestContextHolder获取请求实例,再借助HandlerMapping#getHandler(request)获取方法引用,想问有没有更简便的实现方式?


回答

你的思路其实已经非常贴合Spring的请求处理逻辑了,不过确实有更简洁的方式可以快速拿到目标方法引用,下面给你两种方案参考:

方案一:基于RequestAttributes直接获取(初始思路优化)

Spring在处理请求时,会把匹配到的HandlerMethod存入请求属性中,你可以直接从RequestContextHolder里获取,不需要手动调用HandlerMapping的方法:

// 获取当前请求上下文
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
if (attributes != null) {
    HttpServletRequest request = attributes.getRequest();
    // 从请求属性中直接取出匹配的HandlerMethod
    Object handler = request.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
    if (handler instanceof HandlerMethod) {
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Method targetMethod = handlerMethod.getMethod();
        // 这里targetMethod就是你要的Controller#endpoint()方法引用
    }
}

这个方式避免了手动查找处理器的步骤,直接复用Spring已经处理好的结果。

方案二:注入RequestMappingHandlerMapping直接获取(更简洁)

如果你的组件(比如过滤器、服务类)可以依赖注入,直接注入RequestMappingHandlerMapping,它提供了直接获取HandlerMethod的方法,一步到位:

@Autowired
private RequestMappingHandlerMapping requestMappingHandlerMapping;

public void getTargetHandlerMethod() {
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    if (attributes == null) {
        // 没有请求上下文,做异常处理或返回
        return;
    }
    HttpServletRequest request = attributes.getRequest();
    try {
        HandlerMethod handlerMethod = requestMappingHandlerMapping.getHandlerMethod(request);
        Method targetMethod = handlerMethod.getMethod();
        // 成功拿到目标方法引用
    } catch (NoHandlerFoundException e) {
        // 处理请求没有匹配到任何控制器方法的情况
        e.printStackTrace();
    }
}

这个方式最简洁,因为RequestMappingHandlerMapping已经封装了所有请求匹配的逻辑,直接调用它的getHandlerMethod就能拿到最终的HandlerMethod实例,后续你可以通过handlerMethod.getMethod()拿到方法引用,进而判断方法上的注解。

注意事项

  • 一定要确保在请求上下文存在的场景下调用这些方法,否则RequestContextHolder.getRequestAttributes()会返回null,建议先做非空判断。
  • 如果是在Spring Security的过滤器中,你也可以通过FilterInvocation对象直接获取HttpServletRequest,再套用上面的方案。

内容的提问来源于stack exchange,提问作者Emanuel George Hategan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:11:22