需三步协同:一、判断handler是否为HandlerMethod类型以安全获取Method对象;二、用method.getAnnotation()反射读取@RequirePermission注解,支持方法级与类级双重检查;三、结合用户权限集合校验注解值,标准化字符串后执行交集匹配,失败则返回403。

要在接口切面拦截器中通过反射提取当前执行方法的权限标记,关键不是“拿到注解”本身,而是确保整个链路能稳定、准确地从请求定位到目标方法,并读取其上的自定义权限注解(如 @RequirePermission)。这需要三步协同:正确识别 handler、安全获取 Method 对象、精准提取并解析注解内容。
一、确认 handler 类型并转为 HandlerMethod
Spring MVC 的拦截器或 AOP 切面接收到的 handler 是一个泛型对象,它可能是 HandlerMethod(对应 Controller 方法)、ResourceHttpRequestHandler(静态资源)或其他类型。只有 Controller 方法才可能标注权限注解,所以必须先做类型判断:
- 在
preHandle拦截器中:if (handler instanceof HandlerMethod) { HandlerMethod hm = (HandlerMethod) handler; } - 在 AOP
@Around切面中:if (joinPoint.getThis() instanceof WebMvcConfigurer) { ... }不适用;应直接用joinPoint.getSignature()获取MethodSignature,再调用getMethod() - 跳过非 Controller 类型(如 String、Resource 等),避免
ClassCastException
二、从 Method 对象反射读取权限注解
拿到 Method 实例后,用标准反射 API 获取自定义注解。假设注解类名为 RequirePermission:
- 调用
method.getAnnotation(RequirePermission.class),返回null表示未标注 - 若支持类级 + 方法级双重控制,还需检查所在类:
method.getDeclaringClass().getAnnotation(RequirePermission.class) - 注解字段设计建议为
String[] value() default {}或String module() default ""; String action() default "";,便于后续权限匹配
三、结合上下文完成权限比对
光有注解值还不够,必须关联当前用户权限才能决策是否放行:
- 从
HttpServletRequest中提取 token 或 session,解析出用户角色/权限列表(如从 JWT 的authorities字段) - 若注解值是
{"user:delete", "user:edit"},校验逻辑应为「用户权限集合 ∩ 注解权限集合 ≠ ∅」 - 推荐将权限字符串标准化(小写、去空格、统一分隔符),避免因格式差异导致匹配失败
- 校验失败时,直接设置响应状态码(如 403)并写入错误体,然后
return false(拦截器)或抛出异常(AOP)
不复杂但容易忽略。真正卡点往往不在反射语法,而在 handler 类型误判、注解未设 @Retention(RUNTIME)、或权限字符串未标准化匹配。

















