当前位置:   article > 正文

ThreadLocal(三) 线程上下文实战_bizcontext上下文 存储信息

bizcontext上下文 存储信息

 场景: 某个复杂长链路请求, 例如下单, 需要多组件方法参与,但是对于各种参数聚合, 耦合度很高对于二次开发不方便

解决思路: 利用 ThreadLocal 线程变量来完成, 以后每次改造只需要改造,或者向 ThreadLocal 中增加自己的参数即可,

注意:

  1. 禁止参与多线程!!!否则会导致参数丢失!!!!!
  2. 注意每个线程必须执行 destroy 操作!!!
  3. 建议在入口处进行线程变量初始化和销毁

1. 创建业务上下文类

  1. package net.xinhuamm.converge.model.common;
  2. import lombok.Data;
  3. import net.xinhuamm.converge.bean.news.ConvergeNewsInsertRequest;
  4. import net.xinhuamm.converge.bean.news.ConvergeNewsPushRequest;
  5. import net.xinhuamm.gusteau.usercenter.model.response.admin.AdminContextResponse;
  6. /**
  7. * Description: 业务上下文, 里面有业务配置参数,以及环境变量等
  8. * User: zhouzhou
  9. * Date: 2019-04-15
  10. * Time: 14:53
  11. */
  12. @Data
  13. public class BizContext {
  14. /**
  15. * 当前系统环境
  16. */
  17. private String systemEnv;
  18. /**
  19. * 当前租户id,可为空看当时场景定
  20. */
  21. private Long tenantId;
  22. /**
  23. * 当前租户信息
  24. */
  25. private AdminContextResponse tenantInfo;
  26. /**
  27. * 录入请求
  28. */
  29. private ConvergeNewsInsertRequest convergeNewsInsertRequest;
  30. }

2. 创建 ThreadLocal 线程变量类

  1. package net.xinhuamm.converge.model.common;
  2. import net.xinhuamm.converge.util.SpringContextUtil;
  3. /**
  4. * Description:业务会话
  5. * User: zhouzhou
  6. * Date: 2019-01-15
  7. * Time: 14:54
  8. */
  9. public class BizSession {
  10. // 初始化
  11. private static ThreadLocal<BizContext> INSTANCE = new ThreadLocal<BizContext>(){
  12. @Override
  13. protected BizContext initialValue() {
  14. BizContext context = new BizContext();
  15. if (SpringContextUtil.isTestEnv()){
  16. context.setSystemEnv("test");
  17. }
  18. return context;
  19. }
  20. };
  21. /**
  22. * 获取当前对象实例
  23. * @return
  24. */
  25. public static BizContext currentSession(){
  26. return INSTANCE.get();
  27. }
  28. /**
  29. * 创建会话
  30. * @param bizContext
  31. */
  32. public static void store(BizContext bizContext){
  33. INSTANCE.set(bizContext);
  34. }
  35. public static void destroy(){
  36. INSTANCE.remove();
  37. }
  38. }

 3. 线程变量的初始化与销毁, 这边是在拦截器使用的初始化和销毁

  1. package net.xinhuamm.converge.interceptor;
  2. import net.xinhuamm.converge.model.common.BizContext;
  3. import net.xinhuamm.converge.model.common.BizSession;
  4. import net.xinhuamm.converge.util.SpringContextUtil;
  5. import net.xinhuamm.gusteau.usercenter.model.response.admin.AdminContextResponse;
  6. import org.springframework.stereotype.Component;
  7. import org.springframework.web.servlet.HandlerInterceptor;
  8. import org.springframework.web.servlet.ModelAndView;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. /**
  12. * Description:租户切面
  13. * User: zhouzhou
  14. * Date: 2020-05-19
  15. * Time: 2:45 PM
  16. *
  17. * @author zhouzhou
  18. */
  19. @Component
  20. public class TenantInterceptor implements HandlerInterceptor {
  21. @Override
  22. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  23. if (response.getStatus() == 404 || response.getStatus() == 500) {
  24. return true;
  25. }
  26. BizContext bizContext = BizSession.currentSession();
  27. // 获取用户 token
  28. if (SpringContextUtil.isLocal()){
  29. AdminContextResponse info = new AdminContextResponse();
  30. info.setCurrentTenantId(1L);
  31. info.setRealName("张三");
  32. bizContext.setTenantInfo(info);
  33. }else{
  34. // ResultModel<AdminContextResponse> tokenModel = iUserCenterApiService.getUserByToken();
  35. // if (tokenModel.getCode() != 0 || tokenModel.getData() == null) {
  36. // return false;
  37. // }
  38. // bizContext.setTenantInfo(tokenModel.getData());
  39. // bizContext.setTenantId(tokenModel.getData().getCurrentTenantId());
  40. }
  41. return true;
  42. }
  43. @Override
  44. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
  45. // ignore
  46. }
  47. @Override
  48. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
  49. BizSession.destroy();
  50. }
  51. }

 4. 如何在组件中获取和更新线程变量呢?

  1. // 统计记录日志
  2. ConvergeNewsOperateLogDTO logDTO = new ConvergeNewsOperateLogDTO();
  3. logDTO.setDescription(operateRequest.getDescription());
  4. logDTO.setNewsId(newsId);
  5. logDTO.setOperateType(operateType);
  6. logDTO.setOperator(BizSession.currentSession().getTenantInfo().getRealName());
  7. logService.insert(logDTO);

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/949026
推荐阅读
相关标签
  

闽ICP备14008679号