测试类证明一下ThreadLocal存储的数据是线程程安全的
package com.lin.springboot01;
import org.junit.jupiter.api.Test;
public class testThreadLocal {
@Test
public 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 {
@Override
public 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响应码设置为401
response.setStatus(401);
return false;
}
}
@Override
public 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);
}