接口多态是实现网关协议插拔式接入的核心手段,通过统一protocolhandler接口抽象协议行为,运行时动态绑定实现类,结合协议归一化模型与服务发现机制,达成主逻辑零修改、新增协议仅需上线模块+配置启用。

接口多态不是用来“体现设计感”的,而是让网关真正能插拔式接入新协议、不改主逻辑的关键手段。核心在于:用统一接口抽象协议行为,靠运行时动态绑定具体实现,把“支持什么协议”从代码里移出去。
定义无状态的协议处理接口
所有协议适配逻辑必须收敛到一个清晰、窄契约的接口,比如 ProtocolHandler:
- 声明标准方法:handle(Request req) → Response、canHandle(String protocolName)、getPriority()
- 接口不暴露协议细节(如不包含 isHttp() 或 getGrpcMethod() 这类判断字段)
- 所有实现类(HttpHandler、GrpcHandler、MqttHandler、WebSocketHandler)只负责本协议的编解码、连接管理与语义转换
- 禁止在接口中塞入配置字段或上下文参数——这些应由网关调度层注入
按协议类型动态路由,避免硬编码分支
网关收到请求后,不靠 if-else 或 switch 匹配协议,而是遍历已注册的 ProtocolHandler 实例:
- 先调用 canHandle() 判断是否匹配当前请求特征(如 Content-Type、Upgrade header、协议头标识)
- 再按 getPriority() 排序,选最高优先级且匹配的 handler 执行 handle()
- handler 列表由 Spring 容器自动收集所有实现类 Bean,或从配置中心(Nacos/Apollo)按开关动态加载
- 新增协议只需上线新模块 + 配置启用,网关主流程零修改
协议间数据归一化,靠内部通用模型桥接
多协议适配最难的是语义对齐。不能让每个 handler 直接对接业务服务,而要统一转成网关内部的中间结构:
- 定义通用请求模型 ProtocolRequest:含 method、path、headers、body(byte[])、clientIP、timestamp 等标准化字段
- 每个 handler 负责把原始协议数据(HTTP 的 ServletRequest、gRPC 的 ServerCall、MQTT 的 MqttMessage)解析为 ProtocolRequest
- 业务服务只消费 ProtocolRequest;响应返回后,再由同一 handler 将通用响应 ProtocolResponse 转回对应协议格式
- 这样协议转换逻辑被隔离在 handler 内部,上下游完全无感知
结合服务发现,支撑跨协议微服务协同
当后端服务本身也采用不同协议(如部分用 REST,部分用 gRPC)时,多态要延伸到下游调用侧:
- 定义 ServiceInvoker 接口:invoke(ProtocolRequest req, String serviceId)
- 不同实现类(RestInvoker、GrpcInvoker、DubboInvoker)封装各自协议的客户端调用逻辑
- 网关根据 serviceId 查注册中心,获取其协议类型元数据(存于 Nacos 的 service-meta),再通过工厂获取对应 Invoker 实例
- 上游只知“调服务”,下游协议变更不影响网关代码,也不影响前端请求方式











