当前位置: 首页 > wzjs >正文

西安网站建设阳建网站上线稳定后工作

西安网站建设阳建,网站上线稳定后工作,重庆推广一个网站,购物网站开发意义📝 Part 8:构建统一上下文框架设计与实现(实战篇) 在实际项目中,我们往往需要处理多种上下文来源,例如: Web 请求上下文(RequestContextHolder)日志追踪上下文&#xf…

📝 Part 8:构建统一上下文框架设计与实现(实战篇)

在实际项目中,我们往往需要处理多种上下文来源,例如:

  • Web 请求上下文(RequestContextHolder
  • 日志追踪上下文(MDC
  • Dubbo RPC 上下文(RpcContext
  • 分布式链路追踪(Sleuth
  • 自定义业务上下文(如租户、用户信息等)

如果每个组件都单独维护自己的上下文逻辑,不仅容易出错,而且难以扩展和维护。因此,构建一个统一的上下文管理框架 是非常有必要的。

本文将带你从零开始设计并实现一个可插拔、支持多数据源、自动传播的统一上下文框架,并结合 Spring Boot 实现完整的集成方案。


一、目标设计

我们希望这个框架具备以下能力:

功能描述
✅ 多上下文来源兼容支持 Web、RPC、日志、异步任务等多种上下文来源
✅ 自动传播机制在线程切换、异步调用时自动传播上下文
✅ 配置化扩展可通过配置启用或禁用特定上下文模块
✅ 易于接入 Spring支持与 Spring Boot 的无缝集成
✅ 支持跨服务透传如 Dubbo、Feign 等微服务通信场景
✅ 日志自动注入traceId、userId 等字段自动写入 MDC

二、整体架构设计图

+-----------------------------+
|       ContextManager        |
|   - set(key, value)         |
|   - get(key)                |
|   - clear()                 |
+------------+----------------+|+--------v---------+|  ContextProvider   ||  (接口)            ||  - readFrom()      ||  - writeTo()       |+--------------------+/     |      \/      |       \
+---------+ +----------+ +-----------+
|WebContext | |RpcContext| |LogContext |
|Provider   | |Provider  | |Provider   |
+-----------+ +----------+ +-----------+

三、核心接口定义

1. ContextManager(上下文管理器)

public interface ContextManager {void set(String key, String value);String get(String key);void clear();
}

2. ContextProvider(上下文提供者)

public interface ContextProvider {void readFrom(Map<String, String> contextMap); // 从当前上下文中读取数据到 mapvoid writeTo(Map<String, String> contextMap);   // 将 map 中的数据写入当前上下文
}

四、具体实现示例

1. WebContextProvider(基于 RequestContextHolder)

@Component
public class WebContextProvider implements ContextProvider {@Overridepublic void readFrom(Map<String, String> contextMap) {RequestAttributes attrs = RequestContextHolder.getRequestAttributes();if (attrs != null) {for (String key : attrs.getAttributeNames(RequestAttributes.SCOPE_REQUEST)) {Object val = attrs.getAttribute(key, RequestAttributes.SCOPE_REQUEST);if (val instanceof String) {contextMap.put(key, (String) val);}}}}@Overridepublic void writeTo(Map<String, String> contextMap) {RequestAttributes attrs = RequestContextHolder.getRequestAttributes();if (attrs != null) {contextMap.forEach((key, value) -> attrs.setAttribute(key, value, RequestAttributes.SCOPE_REQUEST));}}
}

2. RpcContextProvider(基于 Dubbo RpcContext)

@Component
@ConditionalOnClass(name = "org.apache.dubbo.rpc.RpcContext")
public class RpcContextProvider implements ContextProvider {@Overridepublic void readFrom(Map<String, String> contextMap) {RpcContext context = RpcContext.getContext();context.getAttachments().forEach(contextMap::put);}@Overridepublic void writeTo(Map<String, String> contextMap) {RpcContext context = RpcContext.getContext();contextMap.forEach(context::setAttachment);}
}

3. LogContextProvider(基于 MDC)

@Component
public class LogContextProvider implements ContextProvider {@Overridepublic void readFrom(Map<String, String> contextMap) {Map<String, String> mdcMap = MDC.getCopyOfContextMap();if (mdcMap != null) {contextMap.putAll(mdcMap);}}@Overridepublic void writeTo(Map<String, String> contextMap) {MDC.setContextMap(contextMap);}
}
}

五、统一上下文管理器实现

@Component
public class DefaultContextManager implements ContextManager {private final List<ContextProvider> providers;public DefaultContextManager(List<ContextProvider> providers) {this.providers = providers;}@Overridepublic void set(String key, String value) {Map<String, String> contextMap = new HashMap<>();contextMap.put(key, value);providers.forEach(p -> p.writeTo(contextMap));}@Overridepublic String get(String key) {Map<String, String> contextMap = new HashMap<>();providers.forEach(p -> p.readFrom(contextMap));return contextMap.get(key);}@Overridepublic void clear() {providers.forEach(p -> p.writeTo(new HashMap<>()));}
}

六、Spring Boot 自动装配

你可以创建一个自动装配模块,用于注册所有上下文提供者。

示例配置类:

@Configuration
public class ContextAutoConfiguration {@Beanpublic ContextManager contextManager(List<ContextProvider> providers) {return new DefaultContextManager(providers);}@Beanpublic ContextProvider webContextProvider() {return new WebContextProvider();}@Bean@ConditionalOnClass(name = "org.apache.dubbo.rpc.RpcContext")public ContextProvider rpcContextProvider() {return new RpcContextProvider();}@Beanpublic ContextProvider logContextProvider() {return new LogContextProvider();}
}

七、拦截器自动注入上下文(可选)

为了确保上下文在请求开始时就已加载,你可以编写一个拦截器自动注入上下文。

@Component
public class ContextInterceptor implements HandlerInterceptor {@Autowiredprivate ContextManager contextManager;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {String traceId = UUID.randomUUID().toString();contextManager.set("traceId", traceId);contextManager.set("userId", request.getHeader("X-User-ID"));return true;}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {contextManager.clear();}
}

八、使用方式(Controller 层)

@RestController
public class UserController {@Autowiredprivate ContextManager contextManager;@GetMapping("/user")public String getCurrentUser() {String userId = contextManager.get("userId");String traceId = contextManager.get("traceId");return String.format("User ID: %s, Trace ID: %s", userId, traceId);}
}

九、异步任务中的自动传播(TTL 支持)

为了保证异步任务也能正确传递上下文,我们可以对 ContextManager 做一层封装:

@Component
public class TtlContextManager implements ContextManager {private static final TransmittableThreadLocal<Map<String, String>> contextHolder = new TransmittableThreadLocal<>();private final ContextManager delegate;public TtlContextManager(ContextManager delegate) {this.delegate = delegate;}@Overridepublic void set(String key, String value) {Map<String, String> map = contextHolder.get();if (map == null) {map = new HashMap<>();}map.put(key, value);contextHolder.set(map);delegate.set(key, value);}@Overridepublic String get(String key) {Map<String, String> map = contextHolder.get();if (map != null) {return map.get(key);}return delegate.get(key);}@Overridepublic void clear() {contextHolder.remove();delegate.clear();}
}

然后替换默认的 ContextManager Bean:

@Bean
public ContextManager contextManager(List<ContextProvider> providers) {return new TtlContextManager(new DefaultContextManager(providers));
}

十、总结建议

场景推荐方案
多上下文来源统一管理设计通用 ContextManager 接口抽象
异步任务上下文丢失使用 TTL 包装上下文管理器
日志自动注入结合 MDC 和 ContextManager
Dubbo 微服务上下文透传使用 RpcContextProvider
Web 请求上下文使用 WebContextProvider
统一日志追踪Sleuth + MDC + ContextManager 联合使用

📌 参考链接

  • TransmittableThreadLocal GitHub
  • Dubbo RpcContext 官方文档
  • Spring Cloud Sleuth 文档

文章转载自:

http://lyJnM1En.ctfwL.cn
http://fUpXS6la.ctfwL.cn
http://qJwTMJgH.ctfwL.cn
http://VKsLdfRp.ctfwL.cn
http://LAH8DVrV.ctfwL.cn
http://SxSuX0tL.ctfwL.cn
http://bcaS0b1A.ctfwL.cn
http://mcLUI86U.ctfwL.cn
http://izqrjyv1.ctfwL.cn
http://l40ozo4d.ctfwL.cn
http://GlXweyny.ctfwL.cn
http://WZUTXl63.ctfwL.cn
http://fB42axNx.ctfwL.cn
http://Phh4lc1e.ctfwL.cn
http://xZVqA8Dj.ctfwL.cn
http://bkNPSmYC.ctfwL.cn
http://AGszsEjQ.ctfwL.cn
http://yAzC5whL.ctfwL.cn
http://V3ViszIW.ctfwL.cn
http://k9H5GILN.ctfwL.cn
http://UbshKRf9.ctfwL.cn
http://r3Av9rJN.ctfwL.cn
http://bYAckEdS.ctfwL.cn
http://QFso9tXm.ctfwL.cn
http://nAglNyHm.ctfwL.cn
http://4o459KBr.ctfwL.cn
http://K4BGqlIc.ctfwL.cn
http://ZUInZBKc.ctfwL.cn
http://rJqte8yT.ctfwL.cn
http://XYo4SXsJ.ctfwL.cn
http://www.dtcms.com/wzjs/747606.html

相关文章:

  • 网站无法访问中国十大网络公司排行榜
  • 网站建设亇金手指下拉排名亅培训班报名
  • 织梦网站自动跳转手机网站电力大学临港校区建设网站
  • 微信可以做网站吗国产在线免费观看高甜电影推荐
  • 南宁个人做网站的vs做网站怎样添加图片
  • 大冶网站开发idea怎么做网站
  • 珠海营销网站建设做个网站多少钱大概
  • 网站链接优化网站统计怎么做
  • 公司电子商务网站建设策划书建筑公司企业宗旨
  • 柞水县住房和城乡建设局网站山西响应式网站设计
  • 花生壳动态域名做网站培训机构推荐
  • 如何下载网站模板网站运营建设的目标
  • 外贸双语网站源码公司网站上线流程
  • 网站建设教程浩森宇特手机网站是用什么开发的
  • pc网站自动转换wap网站襄樊网站建设襄樊
  • 上海专业网站建站品软件工作室网站模板
  • 阿里巴巴外贸网站首页注册公司北京
  • 泰国网站建设有关网站设计的文章
  • 网站建设背景分析论文wordpress取消重定向
  • 网站建设的空间选择做一个网站成本是多少合适
  • 太康做网站公司中国旅游网官网首页
  • 做网站的费用 可以抵扣吗全球搜索引擎网站
  • 建设维护网站运营方案电商营业执照怎么办
  • 各类网站国外网站服务器建设
  • whois查询 站长工具郑州酒店网站建设
  • 做网站赌钱犯法吗近期国外重大新闻事件
  • react企业网站模板网页制作模板教程
  • 青岛谁优化网站做的好教怎么做ppt的网站
  • 电子商务网站建设与管理的论文总结充值中心网站怎么做
  • 搜英文关键词网站wordpress链接在哪里设置