java业务代码,随时取出登录用户信息的思路
方法一,使用继承controller的方式,baseController封装了公共的方法:
1.新建一个BaseController,里面写好公共方法,这些方法可以从springContextHoder取出当前线程绑定的请求信息,例如request和response,在这些方法里对request进行取出或者分析操作,例如header里的token。
2.其他controller则继承BaseController,调用父类的方法,则可以随时取出当前登录用户信息。
注意:因为spring默认是单例的,所以BaseController中不要写成员变量,要取东西直接由方法返回即可
方法二,使用ThreadLocal的方式:
1.新建一个工具类,用来保存用户信息
public class ThreadLocalTool { private ThreadLocalTool(){} private static final ThreadLocal<Student> LOCAL = new ThreadLocal<>(); public static void put(Student sysUser){ LOCAL.set(sysUser); } public static Student get(){ return LOCAL.get(); } public static void remove(){ LOCAL.remove(); } }
2.在过滤器或拦截器获取到用户信息后,调用该工具类put方法,将用户信息存入
我这里就随便用个controller模拟已经登录成功了,然后把数据放进去,使用完毕后一定要remove,把threadloacl清除掉,不然会有内存泄漏风险(听说的,我也没试过)
@RestController @RequestMapping("/test") public class TestController { private static Logger logger = Logger.getLogger(TestController.class); @Resource(name = "testServiceImpl") private TestService testServiceImpl; @GetMapping("/getUser111") public String getUser111(String id) throws InterruptedException {
//保存用户信息 ThreadLocalTool.put(new com.aaa.pojo.Student(id,0,""));
//模拟执行业务 testServiceImpl.getUser();
//清除用户信息 ThreadLocalTool.remove(); return "success了";
3.接口我就省略了,直接看实现类,实现类里用了睡眠,模拟处理业务数据的耗时
@Service(value = "testServiceImpl")
public class TestServiceImpl implements TestService {
@Override
public String getUser() throws InterruptedException {
Student student = ThreadLocalTool.get();
System.out.println("第一次取出来用户 = " + Thread.currentThread().getName() + ": " + student.getName());
Thread.sleep(10000);
System.out.println("第二次取出来用户 = " + Thread.currentThread().getName() + ": " +student.getName());
return null;
}
}
3.用postman准备好多个接口,快速连续发送请求,我这里用了五个
4.看结果吧,可以看到,五次请求分别存进去了5个不同的用户,后面存进去的用户并没有把前面的用户顶掉,每个线程取出来的都是独立的,可见threadlocal是有线程隔离性的