From 8cd74b83dd6538194d2f9da318c5ea7dbca8ef6d Mon Sep 17 00:00:00 2001 From: "Michelle.Chung" <1242874891@qq.com> Date: Mon, 25 Dec 2023 17:48:05 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=96=B0=E5=A2=9E=20ThreadLocalHolder=20?= =?UTF-8?q?=E6=9B=BF=E6=8D=A2=20SaHolder=20;=20add=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?UserInfoInterceptor=20=E6=8B=A6=E6=88=AA=E6=B8=85=E9=99=A4?= =?UTF-8?q?=E7=BA=BF=E7=A8=8B=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=20;=20up?= =?UTF-8?q?date=20=E6=9B=B4=E6=96=B0=20ResourcesConfig=20=E5=9C=A8?= =?UTF-8?q?=E6=8B=A6=E6=88=AA=E5=99=A8=E7=BC=93=E5=AD=98=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BF=A1=E6=81=AF=20;=20update=20=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=20LOGIN=5FUSER=5FKEY=20=E4=B8=BA=E5=B8=B8=E9=87=8F?= =?UTF-8?q?=E4=BE=BF=E4=BA=8E=E5=85=A8=E5=B1=80=E8=B0=83=E7=94=A8=20;=20up?= =?UTF-8?q?date=20=E6=9B=B4=E6=96=B0=20DataPermissionHelper,=20LoginHelper?= =?UTF-8?q?,=20TenantHelper,=20=20PlusWebInvokeTimeInterceptor,=20SysDictT?= =?UTF-8?q?ypeServiceImpl=20=E4=B8=AD=20SaHolder=20->=20ThreadLocalHolder?= =?UTF-8?q?=20;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/core/constant/UserConstants.java | 5 ++ .../core/context/ThreadLocalHolder.java | 55 +++++++++++++++++++ .../mybatis/helper/DataPermissionHelper.java | 10 ++-- .../common/satoken/utils/LoginHelper.java | 18 +++--- .../security/config/SecurityConfig.java | 4 ++ .../common/tenant/helper/TenantHelper.java | 10 ++-- .../common/web/config/ResourcesConfig.java | 3 + .../PlusWebInvokeTimeInterceptor.java | 10 ++-- .../web/interceptor/UserInfoInterceptor.java | 27 +++++++++ .../service/impl/SysDictTypeServiceImpl.java | 10 ++-- 10 files changed, 121 insertions(+), 31 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java create mode 100644 ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/UserInfoInterceptor.java diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java index 6f3b0b96b..b157e24e9 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/constant/UserConstants.java @@ -139,4 +139,9 @@ public interface UserConstants { */ Long SUPER_ADMIN_ID = 1L; + /** + * 登录用户 key + */ + String LOGIN_USER_KEY = "loginUser"; + } diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java new file mode 100644 index 000000000..fcce72af6 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/context/ThreadLocalHolder.java @@ -0,0 +1,55 @@ +package org.dromara.common.core.context; + +import java.util.HashMap; +import java.util.Map; + +/** + * 线程持有类 + * + * @author Michelle.Chung + */ +public class ThreadLocalHolder { + + /** + * 初始化 + */ + private static final ThreadLocal> THREAD_LOCAL = ThreadLocal.withInitial(HashMap::new); + + /** + * 设置值 + * + * @param key 键 + * @param value 值 + */ + public static void set(String key, T value) { + THREAD_LOCAL.get().put(key, value); + } + + /** + * 获取值 + * + * @param key 键 + * @return 值 + */ + @SuppressWarnings("unchecked") + public static T get(String key) { + return (T) THREAD_LOCAL.get().get(key); + } + + /** + * 移除值 + * + * @param key 键 + */ + public static void remove(String key) { + THREAD_LOCAL.get().remove(key); + } + + /** + * 清空值 + */ + public static void clear() { + THREAD_LOCAL.remove(); + } + +} diff --git a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java index 7f6ab1f00..d51382b9e 100644 --- a/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java +++ b/ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/helper/DataPermissionHelper.java @@ -1,12 +1,11 @@ package org.dromara.common.mybatis.helper; -import cn.dev33.satoken.context.SaHolder; -import cn.dev33.satoken.context.model.SaStorage; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import lombok.AccessLevel; import lombok.NoArgsConstructor; +import org.dromara.common.core.context.ThreadLocalHolder; import java.util.HashMap; import java.util.Map; @@ -36,11 +35,10 @@ public class DataPermissionHelper { } public static Map getContext() { - SaStorage saStorage = SaHolder.getStorage(); - Object attribute = saStorage.get(DATA_PERMISSION_KEY); + Object attribute = ThreadLocalHolder.get(DATA_PERMISSION_KEY); if (ObjectUtil.isNull(attribute)) { - saStorage.set(DATA_PERMISSION_KEY, new HashMap<>()); - attribute = saStorage.get(DATA_PERMISSION_KEY); + ThreadLocalHolder.set(DATA_PERMISSION_KEY, new HashMap<>()); + attribute = ThreadLocalHolder.get(DATA_PERMISSION_KEY); } if (attribute instanceof Map map) { return map; diff --git a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java index 2406ba904..633c2c086 100644 --- a/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java +++ b/ruoyi-common/ruoyi-common-satoken/src/main/java/org/dromara/common/satoken/utils/LoginHelper.java @@ -1,7 +1,5 @@ package org.dromara.common.satoken.utils; -import cn.dev33.satoken.context.SaHolder; -import cn.dev33.satoken.context.model.SaStorage; import cn.dev33.satoken.session.SaSession; import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.StpUtil; @@ -11,6 +9,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import org.dromara.common.core.constant.TenantConstants; import org.dromara.common.core.constant.UserConstants; +import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.domain.model.LoginUser; import org.dromara.common.core.enums.UserType; @@ -32,7 +31,7 @@ import java.util.function.Supplier; @NoArgsConstructor(access = AccessLevel.PRIVATE) public class LoginHelper { - public static final String LOGIN_USER_KEY = "loginUser"; + public static final String LOGIN_USER_KEY = UserConstants.LOGIN_USER_KEY; public static final String TENANT_KEY = "tenantId"; public static final String USER_KEY = "userId"; public static final String DEPT_KEY = "deptId"; @@ -47,11 +46,10 @@ public class LoginHelper { * @param model 配置参数 */ public static void login(LoginUser loginUser, SaLoginModel model) { - SaStorage storage = SaHolder.getStorage(); - storage.set(LOGIN_USER_KEY, loginUser); - storage.set(TENANT_KEY, loginUser.getTenantId()); - storage.set(USER_KEY, loginUser.getUserId()); - storage.set(DEPT_KEY, loginUser.getDeptId()); + ThreadLocalHolder.set(LOGIN_USER_KEY, loginUser); + ThreadLocalHolder.set(TENANT_KEY, loginUser.getTenantId()); + ThreadLocalHolder.set(USER_KEY, loginUser.getUserId()); + ThreadLocalHolder.set(DEPT_KEY, loginUser.getDeptId()); model = ObjectUtil.defaultIfNull(model, new SaLoginModel()); StpUtil.login(loginUser.getLoginId(), model.setExtra(TENANT_KEY, loginUser.getTenantId()) @@ -161,10 +159,10 @@ public class LoginHelper { public static Object getStorageIfAbsentSet(String key, Supplier handle) { try { - Object obj = SaHolder.getStorage().get(key); + Object obj = ThreadLocalHolder.get(key); if (ObjectUtil.isNull(obj)) { obj = handle.get(); - SaHolder.getStorage().set(key, obj); + ThreadLocalHolder.set(key, obj); } return obj; } catch (Exception e) { diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java index 63d7eb15b..4f2530a4b 100644 --- a/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java +++ b/ruoyi-common/ruoyi-common-security/src/main/java/org/dromara/common/security/config/SecurityConfig.java @@ -8,6 +8,7 @@ import org.dromara.common.core.utils.ServletUtils; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.satoken.utils.LoginHelper; +import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.security.config.properties.SecurityProperties; import org.dromara.common.security.handler.AllUrlHandler; import lombok.RequiredArgsConstructor; @@ -59,6 +60,9 @@ public class SecurityConfig implements WebMvcConfigurer { StpUtil.getTokenValue()); } + // 保存用户信息 + ThreadLocalHolder.set(LoginHelper.LOGIN_USER_KEY, LoginHelper.getLoginUser()); + // 有效率影响 用于临时测试 // if (log.isDebugEnabled()) { // log.info("剩余有效时间: {}", StpUtil.getTokenTimeout()); diff --git a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java index e830c190a..dd1520433 100644 --- a/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java +++ b/ruoyi-common/ruoyi-common-tenant/src/main/java/org/dromara/common/tenant/helper/TenantHelper.java @@ -1,6 +1,5 @@ package org.dromara.common.tenant.helper; -import cn.dev33.satoken.context.SaHolder; import cn.dev33.satoken.stp.StpUtil; import cn.hutool.core.convert.Convert; import com.alibaba.ttl.TransmittableThreadLocal; @@ -10,6 +9,7 @@ import lombok.AccessLevel; import lombok.NoArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.dromara.common.core.constant.GlobalConstants; +import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.redis.utils.RedisUtils; @@ -94,7 +94,7 @@ public class TenantHelper { } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); RedisUtils.setCacheObject(cacheKey, tenantId); - SaHolder.getStorage().set(cacheKey, tenantId); + ThreadLocalHolder.set(cacheKey, tenantId); } /** @@ -110,12 +110,12 @@ public class TenantHelper { return TEMP_DYNAMIC_TENANT.get(); } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); - String tenantId = (String) SaHolder.getStorage().get(cacheKey); + String tenantId = ThreadLocalHolder.get(cacheKey); if (StringUtils.isNotBlank(tenantId)) { return tenantId; } tenantId = RedisUtils.getCacheObject(cacheKey); - SaHolder.getStorage().set(cacheKey, tenantId); + ThreadLocalHolder.set(cacheKey, tenantId); return tenantId; } @@ -132,7 +132,7 @@ public class TenantHelper { } String cacheKey = DYNAMIC_TENANT_KEY + ":" + LoginHelper.getUserId(); RedisUtils.deleteObject(cacheKey); - SaHolder.getStorage().delete(cacheKey); + ThreadLocalHolder.remove(cacheKey); } /** diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java index 1b78ebcb8..76f17b6fb 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java @@ -1,6 +1,7 @@ package org.dromara.common.web.config; import org.dromara.common.web.interceptor.PlusWebInvokeTimeInterceptor; +import org.dromara.common.web.interceptor.UserInfoInterceptor; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.web.cors.CorsConfiguration; @@ -22,6 +23,8 @@ public class ResourcesConfig implements WebMvcConfigurer { public void addInterceptors(InterceptorRegistry registry) { // 全局访问性能拦截 registry.addInterceptor(new PlusWebInvokeTimeInterceptor()); + // 用户信息拦截 + registry.addInterceptor(new UserInfoInterceptor()); } @Override diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java index 1b4ce3d22..505cc1df7 100644 --- a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/PlusWebInvokeTimeInterceptor.java @@ -2,7 +2,7 @@ package org.dromara.common.web.interceptor; import cn.hutool.core.io.IoUtil; import cn.hutool.core.map.MapUtil; -import com.alibaba.ttl.TransmittableThreadLocal; +import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.utils.SpringUtils; import org.dromara.common.core.utils.StringUtils; import org.dromara.common.json.utils.JsonUtils; @@ -30,7 +30,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { private final String prodProfile = "prod"; - private final TransmittableThreadLocal invokeTimeTL = new TransmittableThreadLocal<>(); + private final String STOP_WATCH_KEY = "stopwatch"; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { @@ -56,7 +56,7 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { } StopWatch stopWatch = new StopWatch(); - invokeTimeTL.set(stopWatch); + ThreadLocalHolder.set(STOP_WATCH_KEY, stopWatch); stopWatch.start(); } return true; @@ -70,10 +70,10 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor { @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { if (!prodProfile.equals(SpringUtils.getActiveProfile())) { - StopWatch stopWatch = invokeTimeTL.get(); + StopWatch stopWatch = ThreadLocalHolder.get(STOP_WATCH_KEY); stopWatch.stop(); log.info("[PLUS]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime()); - invokeTimeTL.remove(); + ThreadLocalHolder.remove(STOP_WATCH_KEY); } } diff --git a/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/UserInfoInterceptor.java b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/UserInfoInterceptor.java new file mode 100644 index 000000000..d7881c2e0 --- /dev/null +++ b/ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/interceptor/UserInfoInterceptor.java @@ -0,0 +1,27 @@ +package org.dromara.common.web.interceptor; + +import cn.hutool.core.util.ObjectUtil; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import org.dromara.common.core.constant.UserConstants; +import org.dromara.common.core.context.ThreadLocalHolder; +import org.springframework.web.servlet.HandlerInterceptor; + +/** + * 用户信息拦截器 + * + * @author Michelle.Chung + */ +@Slf4j +public class UserInfoInterceptor implements HandlerInterceptor { + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + if (ObjectUtil.isNotNull(ThreadLocalHolder.get(UserConstants.LOGIN_USER_KEY))) { + // 清除用户信息 + ThreadLocalHolder.remove(UserConstants.LOGIN_USER_KEY); + } + } + +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java index 346d6bc83..b20bf65c3 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDictTypeServiceImpl.java @@ -1,6 +1,5 @@ package org.dromara.system.service.impl; -import cn.dev33.satoken.context.SaHolder; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -9,6 +8,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import org.dromara.common.core.constant.CacheConstants; import org.dromara.common.core.constant.CacheNames; +import org.dromara.common.core.context.ThreadLocalHolder; import org.dromara.common.core.exception.ServiceException; import org.dromara.common.core.service.DictService; import org.dromara.common.core.utils.MapstructUtils; @@ -221,10 +221,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService @Override public String getDictLabel(String dictType, String dictValue, String separator) { // 优先从本地缓存获取 - List datas = (List) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); + List datas = ThreadLocalHolder.get(CacheConstants.SYS_DICT_KEY + dictType); if (ObjectUtil.isNull(datas)) { datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); + ThreadLocalHolder.set(CacheConstants.SYS_DICT_KEY + dictType, datas); } Map map = StreamUtils.toMap(datas, SysDictDataVo::getDictValue, SysDictDataVo::getDictLabel); @@ -249,10 +249,10 @@ public class SysDictTypeServiceImpl implements ISysDictTypeService, DictService @Override public String getDictValue(String dictType, String dictLabel, String separator) { // 优先从本地缓存获取 - List datas = (List) SaHolder.getStorage().get(CacheConstants.SYS_DICT_KEY + dictType); + List datas = ThreadLocalHolder.get(CacheConstants.SYS_DICT_KEY + dictType); if (ObjectUtil.isNull(datas)) { datas = SpringUtils.getAopProxy(this).selectDictDataByType(dictType); - SaHolder.getStorage().set(CacheConstants.SYS_DICT_KEY + dictType, datas); + ThreadLocalHolder.set(CacheConstants.SYS_DICT_KEY + dictType, datas); } Map map = StreamUtils.toMap(datas, SysDictDataVo::getDictLabel, SysDictDataVo::getDictValue);