feat(context): 新增业务上下文组件并迁移相关功能
- 创建 `hanserwei-spring-boot-starter-biz-context` 模块,封装为starter供其余模块使用 - 迁移 `HeaderUserId2ContextFilter` 和 `LoginUserContextHolder` 到Starter - 使用 `TransmittableThreadLocal` 替代普通 `ThreadLocal` - 在 `han-note-auth` 中引入新的上下文组件依赖 - 调整包结构和日志输出格式 - 异步任务中验证上下文传递功能正常工作
This commit is contained in:
@@ -1,47 +0,0 @@
|
||||
package com.hanserwei.hannote.auth.filter;
|
||||
|
||||
import com.hanserwei.framework.common.constant.GlobalConstants;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class HeaderUserId2ContextFilter extends OncePerRequestFilter {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain chain) throws ServletException, IOException {
|
||||
|
||||
// 从请求头中获取用户 ID
|
||||
String userId = request.getHeader(GlobalConstants.USER_ID);
|
||||
|
||||
log.info("## HeaderUserId2ContextFilter, 用户 ID: {}", userId);
|
||||
|
||||
// 判断请求头中是否存在用户 ID
|
||||
if (StringUtils.isBlank(userId)) {
|
||||
// 若为空,则直接放行
|
||||
chain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果 header 中存在 userId,则设置到 ThreadLocal 中
|
||||
log.info("===== 设置 userId 到 ThreadLocal 中, 用户 ID: {}", userId);
|
||||
LoginUserContextHolder.setUserId(userId);
|
||||
|
||||
try {
|
||||
chain.doFilter(request, response);
|
||||
} finally {
|
||||
// 一定要删除 ThreadLocal ,防止内存泄露
|
||||
LoginUserContextHolder.remove();
|
||||
log.info("===== 删除 ThreadLocal, userId: {}", userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
package com.hanserwei.hannote.auth.filter;
|
||||
|
||||
import com.hanserwei.framework.common.constant.GlobalConstants;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class LoginUserContextHolder {
|
||||
|
||||
// 初始化一个 ThreadLocal 变量
|
||||
private static final ThreadLocal<Map<String, Object>> LOGIN_USER_CONTEXT_THREAD_LOCAL
|
||||
= ThreadLocal.withInitial(HashMap::new);
|
||||
|
||||
|
||||
/**
|
||||
* 设置用户 ID
|
||||
*
|
||||
* @param value 用户 ID
|
||||
*/
|
||||
public static void setUserId(Object value) {
|
||||
LOGIN_USER_CONTEXT_THREAD_LOCAL.get().put(GlobalConstants.USER_ID, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户 ID
|
||||
*
|
||||
* @return 用户 ID
|
||||
*/
|
||||
public static Long getUserId() {
|
||||
Object value = LOGIN_USER_CONTEXT_THREAD_LOCAL.get().get(GlobalConstants.USER_ID);
|
||||
if (Objects.isNull(value)) {
|
||||
return null;
|
||||
}
|
||||
return Long.valueOf(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 ThreadLocal
|
||||
*/
|
||||
public static void remove() {
|
||||
LOGIN_USER_CONTEXT_THREAD_LOCAL.remove();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
|
||||
import com.hanserwei.framework.common.enums.DeletedEnum;
|
||||
import com.hanserwei.framework.common.enums.StatusEnum;
|
||||
import com.hanserwei.framework.common.exception.ApiException;
|
||||
@@ -21,13 +22,14 @@ import com.hanserwei.hannote.auth.domain.mapper.UserDOMapper;
|
||||
import com.hanserwei.hannote.auth.domain.mapper.UserRoleDOMapper;
|
||||
import com.hanserwei.hannote.auth.enums.LoginTypeEnum;
|
||||
import com.hanserwei.hannote.auth.enums.ResponseCodeEnum;
|
||||
import com.hanserwei.hannote.auth.filter.LoginUserContextHolder;
|
||||
import com.hanserwei.hannote.auth.model.vo.user.UserLoginReqVO;
|
||||
import com.hanserwei.hannote.auth.service.UserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
@@ -46,6 +48,8 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
||||
private final UserRoleDOMapper userRoleDOMapper;
|
||||
private final TransactionTemplate transactionTemplate;
|
||||
private final RoleDOMapper roleDOMapper;
|
||||
@Resource(name = "authTaskExecutor")
|
||||
private ThreadPoolTaskExecutor authTaskExecutor;
|
||||
|
||||
@Override
|
||||
public Response<String> loginAndRegister(UserLoginReqVO reqVO) {
|
||||
@@ -147,6 +151,10 @@ public class UserServiceImpl extends ServiceImpl<UserDOMapper, UserDO> implement
|
||||
@Override
|
||||
public Response<?> logout() {
|
||||
Long userId = LoginUserContextHolder.getUserId();
|
||||
authTaskExecutor.submit(() -> {
|
||||
Long userId2 = LoginUserContextHolder.getUserId();
|
||||
log.info("==> 异步线程中获取 userId: {}", userId2);
|
||||
});
|
||||
StpUtil.logout(userId);
|
||||
return Response.success();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user