过Threadlocal+拦截器来进行JWT的校验

在线博客系统的功能分析:
 

redis中可以获取用户信息,但是因为redis中的value是token,要先拿到token解析后才能拿到用户信息,但是token不是每个类中都存在,所以我们去编写ThreadLocal就能够随时获取token

ThreadLocal说简单点就是往一个线程存数据,这个数据只能由这个线程获取,其他线程无法获取这个数据 

以下是我对Threadlocal的理解:
ThreadLocal 主要功能有两个,第一个是可以实现资源对象的线程隔离,让每个线程各用各的资源对象,避免争用引发的线程安全问题,第二个是实现了线程内的资源共享。
    
ThreadLocal的底层原理实现
在ThreadLocal内部维护了一个一个 ThreadLocalMap 类型的成员变量,用来存储资源对象
当我们调用 set 方法,就是以 ThreadLocal 自己作为 key,资源对象作为value,放入当前线程的 ThreadLocalMap 集合中
当调用 get 方法,就是以 ThreadLocal 自己作为 key,到当前线程中查找关联
的资源值
当调用 remove 方法,就是以 ThreadLocal 自己作为 key,移除当前线程关联
的资源值
    
 好的,那关于ThreadLocal会导致内存溢出这个事情,了解吗?
是因为ThreadLocalMap 中的 key 被设计为弱引用,它是被动的被GC调用释
放key,不过关键的是只有key可以得到内存释放,而value不会,因为value
是一个强引用。
在使用ThreadLocal 时都把它作为静态变量(即强引用),因此无法被动依
靠 GC 回收,建议主动的remove 释放 key,这样就能避免内存溢出

功能的实现与搭建:

1.首先是编写UserThreadLocal去维护用户信息的资源对象,里面就定了Threadlocal的三个方法和实例化一个Threadlocal类来绑定用户资源。
package com.jia.utils;/**
 * @author ChenJia
 * @create 2023-06-15 16:58
 */

import com.jia.dao.pojo.SysUser;

/**
 *@ClassName UserThreadLocal
 *@Description 当前用户线程
 *@Author jia
 *@Date 2023/6/15 16:58
 *@Version 1.0
 **/
public class UserThreadLocal {
    //这句话的意思是声明为私有
    private UserThreadLocal (){
    }
    //实例化一个ThreadLocal的类,也就是启用
    private static final ThreadLocal<SysUser> LOCAL = new ThreadLocal<>();

    public static void put(SysUser sysUser){
        LOCAL.set(sysUser);
    }

    public static SysUser get(){
        return LOCAL.get();
    }

    public static void remove() {
        LOCAL.remove();
    }


}
2.然后就可以在我们的拦截器的业务逻辑代码中讲用户信息放入到,拦截完毕后要调用Threadlocal的remove()方法进行key-value移除,避免出现内存泄漏
package com.jia.handler;/**
 * @author ChenJia
 * @create 2023-06-15 16:51
 */

import com.alibaba.fastjson.JSON;
import com.jia.dao.pojo.SysUser;
import com.jia.service.LoginService;
import com.jia.utils.UserThreadLocal;
import com.jia.vo.ErrorCode;
import com.jia.vo.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;

/**
 *@ClassName LoginInterceptor
 *@Description 登录拦截器
 *@Author jia
 *@Date 2023/6/15 16:51
 *@Version 1.0
 **/
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {

 


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        ....#业务代码:JWT校验
  
        UserThreadLocal.put(sysUser);
        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //如果不删除ThreadLocal中的信息,会有内存泄露的风险
        UserThreadLocal.remove();
    }

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值