java new ThreadLocal 储存一个请求上下文的数据 供请求用的代码使用,但不成功?

1、
封装的BaseContext工具类

package com.quanneng.xc_mall.common;

import com.quanneng.xc_mall.entity.Config;

import java.util.HashMap;

import java.util.Map;

public class BaseContext {

private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();

public static Map<String, Object> getLocalMap() {

Map<String, Object> map = THREAD_LOCAL.get();

if (map == null) {

map = new HashMap<>(10);

THREAD_LOCAL.set(map);

}

return map;

}

public static void setLocalMap(Map<String, Object> threadLocalMap) {

THREAD_LOCAL.set(threadLocalMap);

}

public static void set(String key, Object value) {

Map<String, Object> map = getLocalMap();

map.put(key, value);

}

public static Object get(String key) {

Map<String, Object> map = getLocalMap();

return map.getOrDefault(key, "");

}

public static Config getConfig() {

Map<String, Object> map = getLocalMap();

return (Config) map.getOrDefault("config", null);

}

public static void setConfig(Config value) {

Map<String, Object> map = getLocalMap();

map.put("config", value);

}

}

2、
拦截器缓存db.config到redis数据

package com.quanneng.xc_mall.interceptor;

import com.quanneng.xc_mall.common.BaseContext;

import com.quanneng.xc_mall.config.redis.JedisPoolUtilConfig;

import com.quanneng.xc_mall.entity.Config;

import com.quanneng.xc_mall.service.ConfigService;

import com.quanneng.xc_mall.utils.JedisPoolUtil;

import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.Objects;

public class WriteRedisCacheInterceptor implements HandlerInterceptor {

@Resource

private JedisPoolUtilConfig jedisPoolUtilConfig;

@Resource

private JedisPoolUtil jedisPoolUtil;

@Resource

private ConfigService configService;

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {

// 1.获取前端

JedisPoolUtil redisUtil = jedisPoolUtil.setRedisTemplate(jedisPoolUtilConfig.getRedisTemplateByDb(10));

// 2.判断是否存在

Object config = redisUtil.get("config");

// 存在:直接赋值:

if (config != null && !Objects.equals(config, "")) {

BaseContext.setConfig((Config) config);

return true;

}

// 不存在:新建

// 3.查询db

Config byId = configService.getById(1);

if (byId == null) {

throw new RuntimeException("网站参数不存在,请联系网站人员");

}

// 储存:redis

redisUtil.set("config", byId, 60);

// 4.全局储存

BaseContext.setConfig(byId);

return true;

}

}

3、请求中,用到的任意文件中使用

Config   config   = BaseContext.getConfig();

4、请求结束后,管理人员修改了config字段的值,但是请求中获取到的值没变。

这是什么原因呢?
还有,用new ThreadLocal<>()储存不同用户的请求 的用户信息,他们用户信息会串吗,安全吗?

private static final ThreadLocal<Map<String, Object>> THREAD_LOCAL = new ThreadLocal<>();

5、我这段代码有问题吗?
我这个是属于请求上下文吗,跟程序上下文不同,是每一个请求隔离吗?

6、开发时,只有将程序停止掉,再重启,就会更新config的值,除此之外不会更新,并且redis中过期的config还存在。


回答:

  1. 建议加日志,确认代码执行情况
  2. 默认情况下,一个请求运行在一个线程,所以可以使用ThreadLocal保存数据
  3. 接上条,建议在拦截器里做一个清空ThreadLocal的处理,避免某些奇怪的bug

以上是 java new ThreadLocal 储存一个请求上下文的数据 供请求用的代码使用,但不成功? 的全部内容, 来源链接: utcz.com/p/944834.html

回到顶部