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

导读:本篇文章讲解 如何使用ThreadLocal存储用户登录信息?,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

一般我们需要获取当前用户信息,不知道大家脑海里第一印象会是什么呢?用户登录的时候将用户信息保存到缓存中?或者每次解析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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16726.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!