赞
踩
场景: 某个复杂长链路请求, 例如下单, 需要多组件方法参与,但是对于各种参数聚合, 耦合度很高对于二次开发不方便
解决思路: 利用 ThreadLocal 线程变量来完成, 以后每次改造只需要改造,或者向 ThreadLocal 中增加自己的参数即可,
注意:
1. 创建业务上下文类
- package net.xinhuamm.converge.model.common;
-
- import lombok.Data;
- import net.xinhuamm.converge.bean.news.ConvergeNewsInsertRequest;
- import net.xinhuamm.converge.bean.news.ConvergeNewsPushRequest;
- import net.xinhuamm.gusteau.usercenter.model.response.admin.AdminContextResponse;
-
- /**
- * Description: 业务上下文, 里面有业务配置参数,以及环境变量等
- * User: zhouzhou
- * Date: 2019-04-15
- * Time: 14:53
- */
- @Data
- public class BizContext {
- /**
- * 当前系统环境
- */
- private String systemEnv;
- /**
- * 当前租户id,可为空看当时场景定
- */
- private Long tenantId;
-
- /**
- * 当前租户信息
- */
- private AdminContextResponse tenantInfo;
-
- /**
- * 录入请求
- */
- private ConvergeNewsInsertRequest convergeNewsInsertRequest;
-
-
-
- }
2. 创建 ThreadLocal 线程变量类
- package net.xinhuamm.converge.model.common;
-
-
- import net.xinhuamm.converge.util.SpringContextUtil;
-
- /**
- * Description:业务会话
- * User: zhouzhou
- * Date: 2019-01-15
- * Time: 14:54
- */
- public class BizSession {
-
- // 初始化
- private static ThreadLocal<BizContext> INSTANCE = new ThreadLocal<BizContext>(){
- @Override
- protected BizContext initialValue() {
- BizContext context = new BizContext();
- if (SpringContextUtil.isTestEnv()){
- context.setSystemEnv("test");
- }
- return context;
- }
- };
-
- /**
- * 获取当前对象实例
- * @return
- */
- public static BizContext currentSession(){
- return INSTANCE.get();
- }
-
- /**
- * 创建会话
- * @param bizContext
- */
- public static void store(BizContext bizContext){
- INSTANCE.set(bizContext);
- }
-
- public static void destroy(){
- INSTANCE.remove();
- }
- }
3. 线程变量的初始化与销毁, 这边是在拦截器使用的初始化和销毁
- package net.xinhuamm.converge.interceptor;
-
- import net.xinhuamm.converge.model.common.BizContext;
- import net.xinhuamm.converge.model.common.BizSession;
- import net.xinhuamm.converge.util.SpringContextUtil;
- import net.xinhuamm.gusteau.usercenter.model.response.admin.AdminContextResponse;
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- /**
- * Description:租户切面
- * User: zhouzhou
- * Date: 2020-05-19
- * Time: 2:45 PM
- *
- * @author zhouzhou
- */
- @Component
- public class TenantInterceptor implements HandlerInterceptor {
-
-
-
-
- @Override
- public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- if (response.getStatus() == 404 || response.getStatus() == 500) {
- return true;
- }
- BizContext bizContext = BizSession.currentSession();
-
- // 获取用户 token
- if (SpringContextUtil.isLocal()){
- AdminContextResponse info = new AdminContextResponse();
- info.setCurrentTenantId(1L);
- info.setRealName("张三");
- bizContext.setTenantInfo(info);
- }else{
- // ResultModel<AdminContextResponse> tokenModel = iUserCenterApiService.getUserByToken();
- // if (tokenModel.getCode() != 0 || tokenModel.getData() == null) {
- // return false;
- // }
- // bizContext.setTenantInfo(tokenModel.getData());
- // bizContext.setTenantId(tokenModel.getData().getCurrentTenantId());
- }
-
- return true;
- }
-
- @Override
- public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
- // ignore
- }
-
- @Override
- public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
- BizSession.destroy();
- }
- }
4. 如何在组件中获取和更新线程变量呢?
- // 统计记录日志
- ConvergeNewsOperateLogDTO logDTO = new ConvergeNewsOperateLogDTO();
- logDTO.setDescription(operateRequest.getDescription());
- logDTO.setNewsId(newsId);
- logDTO.setOperateType(operateType);
- logDTO.setOperator(BizSession.currentSession().getTenantInfo().getRealName());
- logService.insert(logDTO);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。