优雅的使用 ThreadLocal
维持线程封闭性的一种更规范的方法就是使用 ThreadLocal,这个类能使线程中的某个值与保存的值的对象关联起来。ThreadLocal 提供 get 和 set 等接口或方法,这些方法为每一个使用这个变量的线程都存有一份独立的副本,因此 get 总是返回由当前线程在调用 set 时设置的最新值。ThreadLocal 有如下方法
1、get() 方法是用来获取 ThreadLocal 在当前线程中保存的变量副本
2、set() 用来设置当前线程中变量的副本
3、remove() 用来移除当前线程中变量的副本
4、initialValue() 是一个 protected 方法,一般是用来在使用时进行重写的,如果在没有 set 的时候就调用 get,会调用 initialValue 方法初始化内容。为了使用的更放心,我们简单的
首先准备一个 BaseSigntureRequest 类用来存放公共参数
- public class BaseSignatureRequest {
- private String device;
- public String getDevice() {
- return device;
- }
- public void setDevice(String device) {
- this.device = device;
- }
- }
复制代码
- public class ThreadLocalCache {
- public static ThreadLocal<BaseSignatureRequest>
- baseSignatureRequestThreadLocal = new ThreadLocal<>();
- }
复制代码
然后编写一个 Interceptor,在请求的时候获取 device 参数,存入当前线程的 ThreadLocal 中。这里需要注意的是,重写了 afterCompletion 方法,当请求结束的时候把 ThreadLocalremove,移除不必须要键值对。
- public class ParameterInterceptor implements HandlerInterceptor {
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
- Object handler) throws Exception {
- String device = request.getParameter(“device”);
- BaseSignatureRequest baseSignatureRequest = new BaseSignatureRequest();
- baseSignatureRequest.setDevice(device);
- ThreadLocalCache.baseSignatureRequestThreadLocal.set(baseSignatureRequest);
- return true;
- }
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
- Object handler, Exception ex) throws Exception {
- ThreadLocalCache.baseSignatureRequestThreadLocal.remove();
- }
- @Override
- public void postHandle(HttpServletRequest httpServletRequest,
- HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
- }
- }