1. 配置拦截器:

/**
 * 登录拦截器
 */
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1.获取session
        HttpSession session = request.getSession();
        //2.获取session中的用户
        User user = (User) session.getAttribute("user");
        //3.判断用户是否存在
        //4.不存在,拦截
        if(user == null){
            response.setStatus(401);
            return false;
        }
        //5.存在,保存用户到ThreadLocal
        UserHolder.saveUser(user);
        //6.放行
        return true;
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //释放用户
        UserHolder.removeUser();
    }
}

----------
2.注册拦截器:
@Configuration
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
    //添加拦截器
    @Autowired
    private LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册拦截器:{}",loginInterceptor);
        registry.addInterceptor(loginInterceptor)
                //.addPathPatterns("/user/**")
                .excludePathPatterns("user/code")
                .excludePathPatterns("user/login");
    }
}
---------------------------------------------------------
细节:
1.如果不添加 .addPathPatterns()会默认拦截所有请求
2.给registry添加路径时的通配符规则(Ant 风格通配符);

1. ? - 匹配单个字符
作用:匹配任何单个字符(除了路径分隔符 /)

示例:"/user/?"

✅ 匹配:/user/1, /user/a, /user/X

❌ 不匹配:/user/, /user/12, /user/abc, /user/a/b

2. * - 匹配单层路径
作用:匹配零个或多个字符(除了路径分隔符 /),只能匹配一层路径

示例:"/user/*"

✅ 匹配:/user/, /user/profile, /user/123, /user/abc.html

❌ 不匹配:/user/profile/settings, /user/123/orders

3. ** - 匹配多层路径
作用:匹配零个或多个目录和字符,可以跨越多层路径

示例:"/user/**"

✅ 匹配:/user/, /user/profile, /user/profile/settings, /user/123/orders/456

4. {name} - 路径变量(Spring 扩展)
作用:匹配路径片段并将其捕获为变量

示例:"/user/{userId}", "/api/{version}/products"

匹配 /user/123 → userId=123

匹配 /api/v1/products → version=v1

5. {regex} - 正则表达式匹配(Spring 扩展)
作用:使用正则表达式定义更精确的匹配模式

示例:"/user/{id:\\d+}", "/file/{name:[a-z-]+}.{ext}"

{id:\\d+} 只匹配数字

{name:[a-z-]+} 匹配小写字母和连字符
------------------------------------------------------------
2.拦截器的拦截先后顺序,一般先注册的先拦截,也可以设置order值,值越小越先拦截;
  例如:
@Configuration
@Slf4j
public class MvcConfig implements WebMvcConfigurer {
    //添加拦截器

    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .excludePathPatterns("/user/code","/user/login","/blog/hot","/upload/**","/shop-type/**","/voucher/**","/shop/**").order(1); //拦截与登录相关功能的请求

        registry.addInterceptor(new RefreshTokenInterceptor(stringRedisTemplate)).order(0); //拦截所有请求
    }

}
第二个添加的拦截器反而先执行,因为设置的order值更小;
--------------------------------------------------------------