如何使用ThreadLocal存储用户登录信息?

一般我们需要获取当前用户信息,不知道大家脑海里第一印象会是什么呢?用户登录的时候将用户信息保存到缓存中?或者每次解析token,然后一层一层的传递?这样会不会导致代码太过耦合呢。那我们如何解决这种问题呢?

没错,我们可以使用ThreadLocal来解决该问题。ThreadLocal可以将用户信息保存在线程中,当请求结束后我们在把保存的信息清除掉。这样我们才开发的时候就可以直接从全局的ThreadLocal中很方便的获取用户信息。

实现该功能很简单,总共分为三个步骤:

  • 首先创建ThreadLocal类,在其中设置相关的添加、获取以及删除方法。
  • 创建登录拦截器,重新其中的preHandle()afterCompletion()方法。
  • 注册拦截器

我们这里通过一个简答的例子来了解大致流程,在日常开发中我们可以根据自己需要去获取用户信息,比如从token解析等。


ThreadLocal类

public class UserInfoThreadHolder {

    /**
     * 保存用户对象的ThreadLocal
     */
    private static final ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

    /**
     * 添加当前登录用户方法
     */
    public static void addCurrentUser(User user){
        userThreadLocal.set(user);
    }

    public static User getCurrentUser(){
        return userThreadLocal.get();
    }


    /**
     * 防止内存泄漏
     */
    public static void remove(){
        userThreadLocal.remove();
    }

}

拦截器

我们在preHandle()方法中根据自己的需要将用户的登录信息存放之ThreadLocal中即可。

然后最后记得清除相关数据以避免内存泄漏。

public class LoginInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        User user = new User();
        user.setNickName("cc");
        UserInfoThreadHolder.addCurrentUser(user);
        return true;
    }

    /**
     * 避免内存泄露
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        UserInfoThreadHolder.remove();
    }
}

注册

@Configuration
@ComponentScan(basePackages = "com.example.carrental")
public class WebMvcConfig implements WebMvcConfigurer {
    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new LoginInterceptor())
                .addPathPatterns("/**")
                .excludePathPatterns("/user/wx/login");//开放登录路径
    }

}

测试

做完以上步骤后,我们就可以自行编写接口测试了。直接通过ThreadLocal返回用户的登录信息。

@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/test")
    public String test(){
        return UserInfoThreadHolder.getCurrentUser().getNickName();
    }

}

image-20220226215202754

  • 8
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

、楽.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值