通过 Spring WebFlux 源码分析装饰器模式

🎯 通过 Spring WebFlux 源码分析装饰器模式

在日常 Java 开发中,我们经常会遇到这样的需求:在不动原有代码的情况下,增强其功能 。这时,设计模式中的一位老朋友就闪亮登场了 ------ 装饰器模式(Decorator Pattern)!

为了让你更直观地理解这个经典模式,今天我们就从 Spring WebFlux 中的一个实际案例 ------ ServerHttpRequestDecorator 出发,来一场源码级别的深度解析!🚀


🧠 什么是装饰器模式?

装饰器模式是一种结构型设计模式,它允许我们在不改变原始类的前提下,为对象添加新的功能。

想象一下,如果你要给一杯咖啡加奶加糖,但不希望动到咖啡本身的制作过程,就可以使用"装饰器"来一步步"包裹"它。

📌 UML 结构图回顾

css 复制代码
Component(抽象组件)
   ↑
ConcreteComponent(具体组件)
   ↑
Decorator(抽象装饰器)
   ↑
ConcreteDecoratorA / B(具体装饰器)

🔍 ServerHttpRequestDecorator 是个啥?

在 Spring WebFlux 中,ServerHttpRequest 表示 HTTP 请求。而 ServerHttpRequestDecorator 是它的一个包装器,实现了装饰器模式的核心思想。

👇 先来看看它的基本结构:

java 复制代码
public class ServerHttpRequestDecorator implements ServerHttpRequest {

    private final ServerHttpRequest delegate;

    public ServerHttpRequestDecorator(ServerHttpRequest delegate) {
        Assert.notNull(delegate, "Delegate is required");
        this.delegate = delegate;
    }

    @Override
    public HttpMethod getMethod() {
        return this.delegate.getMethod();
    }

    // 大多数方法都简单委托给 delegate ...
}

🎯 可以看出,这个类只是把原始请求"包起来",保留所有原有行为的同时,还可以通过子类进行功能增强。


🧩 装饰器模式的三板斧

在 ServerHttpRequestDecorator 中,我们能看到装饰器模式的三个关键组成:

  1. ✅ 实现相同接口 ------ 装饰器类和被装饰对象都实现 ServerHttpRequest 接口。
  2. ✅ 持有原始对象引用 ------ 用组合方式持有 delegate。
  3. ✅ 灵活扩展行为 ------ 可以重写任意方法添加逻辑,比如读取请求体、修改头部等。

✏️ 实战演示:记录请求体日志

我们来写一个自己的装饰器 ------ 在请求体被读取时打印日志:

java 复制代码
public class LoggingServerHttpRequestDecorator extends ServerHttpRequestDecorator {

    public LoggingServerHttpRequestDecorator(ServerHttpRequest delegate) {
        super(delegate);
    }

    @Override
    public Flux<DataBuffer> getBody() {
        return super.getBody().map(dataBuffer -> {
            // 读取请求体内容
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            DataBufferUtils.release(dataBuffer);
            String bodyString = new String(bytes, StandardCharsets.UTF_8);
            System.out.println("📥 请求体内容: " + bodyString);

            // 包装返回新的 DataBuffer
            DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
            return bufferFactory.wrap(bytes);
        });
    }
}

你可以把这个装饰器放在 WebFilter 中,对所有请求都打印日志,不动 Controller,一样搞定! 🔧


🌟 装饰器模式的优势

优点 描述
💡 遵循开闭原则 不修改原始类也能扩展功能
🧱 支持功能叠加 可多个装饰器组合形成链式增强
🔄 动态灵活 可在运行时选择性应用装饰器

📌 装饰器适用的场景

  • 你想要增强一个类的行为,但不想继承它?用装饰器!
  • 多个类都需要相似增强逻辑?装饰器走起!
  • 想要根据条件灵活组合功能?还是装饰器!

🧾 总结

装饰器模式不仅是设计模式书中的理论知识,更是实际开发中的利器。Spring WebFlux 中的 ServerHttpRequestDecorator 是它最典型的实践之一。

通过对它的源码剖析,我们可以掌握:

  • ✅ 如何封装已有对象
  • ✅ 如何在保持接口一致的前提下扩展行为
  • ✅ 如何构建灵活可扩展的系统

希望这篇文章能帮你在"装饰器"这条路上走得更远更稳!🌱


📚 延伸阅读推荐:

  • 《设计模式:可复用面向对象软件的基础》(GoF)
  • Spring WebFlux 源码中 ServerHttpRequestDecorator
  • 响应式流与 DataBuffer 深入解析
相关推荐
今天的砖头有点烫手啊13 小时前
Java 对象内存布局:压缩指针、对齐填充与 JOL 实测
java·jvm
devilnumber13 小时前
Lambda 表达式(Java)优缺点清晰分析
java·开发语言·python
时空节拍AI数字人13 小时前
博物馆数字人讲解系统设计:知识库 schema、展项联动协议与时序控制
java·服务器·前端·人工智能·ai·语音识别
GG.WinGel13 小时前
三元组中心问题
java·数据结构·算法·青少年编程·蓝桥杯
vailee14 小时前
42 万字符的工具输出压进 6,945 token:Agent 长会话的上下文治理实践
java·大数据·人工智能·prompt工程·rag·上下文管理
weixin_4487717214 小时前
Spring框架之ConfigurableApplicationContext源码学习
java·spring
无巧不成书021814 小时前
Tomcat部署JSP文件完整指南:手动部署+IDEA工程化实现 附404访问错误全排查
java·ide·windows·tomcat·intellij-idea·js
曹牧14 小时前
Eclipse:Subclipse
java·ide·eclipse
weixin_4487717214 小时前
Spring框架之ApplicationContext源码学习
java·学习·spring
白露与泡影14 小时前
Spring AI Alibaba -- 文生图、文生音及向量化
java·人工智能·spring