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还存在。
回答:
- 建议加日志,确认代码执行情况
- 默认情况下,一个请求运行在一个线程,所以可以使用ThreadLocal保存数据
- 接上条,建议在拦截器里做一个清空ThreadLocal的处理,避免某些奇怪的bug
以上是 java new ThreadLocal 储存一个请求上下文的数据 供请求用的代码使用,但不成功? 的全部内容, 来源链接: utcz.com/p/944834.html