Spring拦截器和ThreadLocal的使用示例

ThreadLocal:

  • 线程局部变量,本质是一个Map集合,用于对象存储
  • 线程之内 信息共享
  • 线程之间 信息隔离
    在这里插入图片描述

ThreadLocal3个方法:

  • set(T value) :设置当前线程绑定的变量
  • get():获取当前线程绑定的变量
  • remove() :移除当前线程绑定的变量

ThreadLocal可以配合Spring拦截器一起使用

Spring拦截器三个方法:

  • preHandle() : 在目标方法之前执行,一般用于预处理
  • postHandle():在目标方法执行之后执行,一般用于后处理
  • afterCompletion():整个请求处理完毕,在视图渲染完毕时回调,一般用于资源的清理或性能的统计

ThreadLocal与Spring拦截器实现思路:
在这里插入图片描述
代码实现:

1、在reggie-common下创建com.itheima.reggie.common.EmployeeHolder

package com.itheima.reggie.config;

import com.itheima.reggie.domain.Employee;

//ThreadLocal操作工具类
public class EmployeeHolder {

    //维护ThreadLocal对象
    private static ThreadLocal<Employee> threadLocal = new ThreadLocal<>();

    //放入User
    public static void set(Employee employee) {
        threadLocal.set(employee);
    }

    //获取User
    public static Employee get() {
        return threadLocal.get();
    }

    //移除User
    public static void remove() {
        threadLocal.remove();
    }
}

2、修改com.itheima.reggie.interceptor.LoginCheckInterceptor

//登录拦截器
@Component
public class LoginCheckInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //1、判断登录状态,如果已登录,则直接放行
        Employee employee = (Employee) request.getSession().getAttribute(Constant.SESSION_EMPLOYEE);
        if (employee != null) {
            //将employ方法ThreadLocal
            EmployeeHolder.set(employee);
            return true;
        }

        //2、如果未登录,禁止通行,返回错误
        String json = JSON.toJSONString(ResultInfo.error("NOTLOGIN"));
        response.getWriter().write(json);
        return false;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        EmployeeHolder.remove();
    }
}

3、修改com.itheima.reggie.config.MyMetaObjectHandler

//自定义元数据对象处理器
//自动填充逻辑
@Component
@Slf4j
public class MyMetaObjectHandler implements MetaObjectHandler {
    //插入操作,自动填充
    @Override
    public void insertFill(MetaObject metaObject) {
        metaObject.setValue("createTime", new Date());
        metaObject.setValue("updateTime", new Date());
        // 从ThreadLocal中获取Employee的对象
        Employee employee = EmployeeHolder.get();
        if (employee != null) {
            metaObject.setValue("createUser", employee.getId());
            metaObject.setValue("updateUser", employee.getId());
        }
    }

    //更新操作,自动填充
    @Override
    public void updateFill(MetaObject metaObject) {
        metaObject.setValue("updateTime", new Date());
        Employee employee = EmployeeHolder.get();
        if (employee != null) {
            metaObject.setValue("updateUser", employee.getId());
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中使用ThreadLocal存放请求的header信息可以通过以下步骤来实现: 1. 创建一个自定义的拦截器(Interceptor),用于在每个请求进入控制器方法之前进行拦截和处理。 2. 在拦截器中,使用ThreadLocal类来存储请求的header信息。ThreadLocal是一个线程局部变量,它可以确保每个线程都有自己独立的副本。这样就可以确保在处理请求的同时,不会出现线程安全问题。 下面是一个简单的示例代码: ```java public class HeaderInterceptor extends HandlerInterceptorAdapter { private static final ThreadLocal<Map<String, String>> headerThreadLocal = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Map<String, String> headers = new HashMap<>(); // 将请求的header信息存储到ThreadLocal中 Enumeration<String> headerNames = request.getHeaderNames(); while (headerNames.hasMoreElements()) { String headerName = headerNames.nextElement(); String headerValue = request.getHeader(headerName); headers.put(headerName, headerValue); } headerThreadLocal.set(headers); return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { // 请求处理完成后,清除ThreadLocal中的数据,避免内存泄漏 headerThreadLocal.remove(); } public static Map<String, String> getHeaders() { return headerThreadLocal.get(); } } ``` 3. 在Spring Boot的配置类中注册拦截器: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new HeaderInterceptor()); } } ``` 4. 在控制器中可以通过调用HeaderInterceptor的getHeaders方法来获取当前请求的header信息: ```java @RestController public class MyController { @GetMapping("/myEndpoint") public String myEndpoint() { Map<String, String> headers = HeaderInterceptor.getHeaders(); // 使用获取到的header信息进行处理 // ... return "Response"; } } ``` 这样,你就可以在Spring Boot中使用ThreadLocal存放请求的header信息了。每个请求都会有自己独立的header信息,不会相互干扰。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值