Spring Boot 2.7能否为指定Controller绑定HandlerInterceptor?
在Spring Boot 2.7中直接将拦截器绑定到特定Controller的实现方案
当然可以实现无需手动维护路径、直接指定拦截特定Controller的需求,下面提供两种可靠的实现方式:
方案一:自定义注解标记目标Controller
这种方式直观灵活,通过自定义注解标记需要拦截的Controller,拦截器内部判断请求对应的Controller是否带有该注解,从而决定是否执行拦截逻辑。
- 定义自定义标记注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface InterceptTargetController { }
- 在目标Controller上添加该注解
@InterceptTargetController @RestController @RequestMapping("/demo") public class DemoController { // 各类接口方法... }
- 修改拦截器,增加注解判断逻辑
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 仅处理Controller方法的请求 if (handler instanceof HandlerMethod handlerMethod) { Class<?> controllerClass = handlerMethod.getBeanType(); // 检查当前请求对应的Controller是否带有标记注解 if (controllerClass.isAnnotationPresent(InterceptTargetController.class)) { // 执行你的拦截逻辑 return true; } } // 非目标Controller的请求直接放行 return true; } }
- 全局配置拦截器(无需指定路径)
@Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { private final MyInterceptor interceptor; @Override public void addInterceptors(InterceptorRegistry registry) { // 全局注册拦截器,拦截范围由注解逻辑控制 registry.addInterceptor(interceptor); } }
方案二:动态提取目标Controller的所有映射路径
如果不想用注解,可以通过Spring内置的RequestMappingHandlerMapping获取目标Controller的所有接口路径,动态添加到拦截器配置中,能覆盖该Controller下所有类级、方法级的请求映射。
修改WebConfig配置类:
@Configuration @RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { private final MyInterceptor interceptor; // 注入Spring维护的请求映射处理器 private final RequestMappingHandlerMapping requestMappingHandlerMapping; @Override public void addInterceptors(InterceptorRegistry registry) { InterceptorRegistration registration = registry.addInterceptor(interceptor); // 指定要拦截的目标Controller的Class对象 Class<?> targetController = DemoController.class; // 遍历所有已注册的请求映射 Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) { HandlerMethod handlerMethod = entry.getValue(); // 判断当前映射是否属于目标Controller if (targetController.equals(handlerMethod.getBeanType())) { // 提取该映射的所有路径模式并添加到拦截器 Set<String> pathPatterns = entry.getKey().getPatternsCondition().getPatterns(); registration.addPathPatterns(pathPatterns); } } } }
这种方式会自动收集目标Controller下的所有接口路径,无需手动维护路径与Controller的一致性,完美覆盖该Controller的所有请求。
内容的提问来源于stack exchange,提问作者Ben Ketteridge
相关产品推荐
相关产品推荐

