你有没有想过你平时拦截器的写法是错的?下面写法各位应该都见过或者写过吧?
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new HttpHandlerInterceptor()).addPathPatterns("/**");
}
}
addPathPatterns("/**")
是一种精细化拦截的写法,但是这里使用/**
来精细化拦截所有请求么?
精细化的全局拦截?
其实也无伤大雅,只不过springmvc会为每个请求构建专属的拦截器链,如果拦截器注册时加上
addPathPatterns
,excludePathPatterns
,pathMatcher
等方法的话,那么这个全局拦截器就会变为转专属拦截器,只针对特定的路径才会在拦截器链加入它。
addPathPatterns("/**")
会导致的问题是全局拦截器在每次加入拦截器链前都多了一重校验,仅此而已。
什么是MappedInterceptor
MappedInterceptor
是 Spring MVC 提供的一种机制,用于在请求处理流程中拦截特定路径的请求。与常规的 HandlerInterceptor
不同,MappedInterceptor
提供了更灵活的路径匹配功能,使得开发者可以更精细地控制拦截器的应用范围。
当你添加了addPathPatterns("/**")
之后,在注册拦截器时,SpringMvc会将你写的拦截器包装成MappedInterceptor
!
MappedInterceptor作用
MappedInterceptor
的主要作用是将一个或多个 HandlerInterceptor
绑定到特定的 URL 路径模式。这样,可以根据请求路径来决定是否应用某个拦截器,从而提供细粒度的拦截控制。
使用范围
MappedInterceptor
主要用于以下场景:
- 路径匹配:
- 根据 URL 路径模式匹配来应用拦截器。例如,可以设置拦截器只应用于
/admin/**
路径下的请求。
- 根据 URL 路径模式匹配来应用拦截器。例如,可以设置拦截器只应用于
- 条件拦截:
- 在大型应用中,可以根据请求路径条件性地应用不同的拦截器,从而避免在所有请求中执行不必要的拦截逻辑,提高性能。
- 模块化拦截:
- 可以为不同的模块设置不同的拦截器,从而实现模块化管理。例如,为用户模块、订单模块等设置不同的拦截器。
示例代码
以下是一个使用 MappedInterceptor
的示例:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.MappedInterceptor;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public MappedInterceptor adminInterceptor() {
return new MappedInterceptor(new String[]{"/admin/**"}, new AdminInterceptor());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(adminInterceptor());
}
}
public class AdminInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 在请求处理之前执行的逻辑
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
// 在请求处理之后但在视图渲染之前执行的逻辑
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
// 在整个请求完成之后执行的逻辑
}
}
在这个示例中,MappedInterceptor
被配置为只拦截 /admin/**
路径下的请求,并应用 AdminInterceptor
。
总结:
拦截器链是定制化的,是根据每次请求去定制化的。
全局拦截器与精细化拦截器的主要区别在于是否添加了路径匹配。