feat(context): 新增业务上下文组件并迁移相关功能
- 创建 `hanserwei-spring-boot-starter-biz-context` 模块,封装为starter供其余模块使用 - 迁移 `HeaderUserId2ContextFilter` 和 `LoginUserContextHolder` 到Starter - 使用 `TransmittableThreadLocal` 替代普通 `ThreadLocal` - 在 `han-note-auth` 中引入新的上下文组件依赖 - 调整包结构和日志输出格式 - 异步任务中验证上下文传递功能正常工作
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.hanserwei.framework.biz.context.config;
|
||||
|
||||
import com.hanserwei.framework.biz.context.filter.HeaderUserId2ContextFilter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
@AutoConfiguration
|
||||
public class ContextAutoConfiguration {
|
||||
@Bean
|
||||
public HeaderUserId2ContextFilter headerUserId2ContextFilter() {
|
||||
return new HeaderUserId2ContextFilter();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.hanserwei.framework.biz.context.filter;
|
||||
|
||||
import com.hanserwei.framework.biz.context.holder.LoginUserContextHolder;
|
||||
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;
|
||||
|
||||
@Slf4j
|
||||
public class HeaderUserId2ContextFilter extends OncePerRequestFilter {
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain chain) throws ServletException, IOException {
|
||||
log.info("=====> HeaderUserId2ContextFilter 开始执行");
|
||||
// 从请求头中获取用户 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.hanserwei.framework.biz.context.holder;
|
||||
|
||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||
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
|
||||
= TransmittableThreadLocal.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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
com.hanserwei.framework.biz.context.config.ContextAutoConfiguration
|
||||
Reference in New Issue
Block a user