测试类证明一下ThreadLocal存储的数据是线程程安全的
package com.lin.springboot01;import org.junit.jupiter.api.Test;public class testThreadLocal {@Testpublic void testThreadLocalSetAndGet(){//提供一个ThreadLocal对象ThreadLocal t1 = new ThreadLocal();new Thread(()->{t1.set("张三");System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());},"绿色").start();new Thread(()->{t1.set("李四");System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());System.out.println(Thread.currentThread().getName()+":"+t1.get());},"黄色").start();}}
接上一篇获取用户详细信息,用ThreadLocal进行优化
ThreadLocalUtil:工具类
package com.lin.springboot01.utils;public class ThreadLocalUtil {//提供ThreadLocal对象private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();//根据键获取值public static <T> T get(){return (T) THREAD_LOCAL.get();}//存储键值对public static void set(Object value){THREAD_LOCAL.set(value);}//清除Threadlocal 防止内存泄露public static void remove(){THREAD_LOCAL.remove();}
}
LoginInterceptor:ThreadLocalUtil.set(claims)将数据存储到ThreadLocal中
package com.lin.springboot01.interceptors;import com.lin.springboot01.pojo.Result;
import com.lin.springboot01.utils.JwtUtil;
import com.lin.springboot01.utils.ThreadLocalUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;import java.util.Map;@Component
public class LoginInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String token = request.getHeader("Authorization");try {//能否解析成功Map<String, Object> claims = JwtUtil.parseToken(token);//把业务数据存储到ThreadLocal中ThreadLocalUtil.set(claims);//放行return true;} catch (Exception e) {//解析失败,httpServletResponse响应码设置为401response.setStatus(401);return false;}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {//清空Threadlocal中的数据ThreadLocalUtil.remove();}
}
UserController:改用ThreadLocalUtil获取用户name,在把参数传给findByName方法
@GetMapping("/userInfo")public Result<User> userInfo(/*@RequestHeader(name="Authorization") String token*/){/* Map<String, Object> map = JwtUtil.parseToken(token);String username = (String) map.get("username");*/Map<String,Object> map = ThreadLocalUtil.get();String username = (String) map.get("username");User user = userService.findByName(username);return Result.success(user);}