【设计模式】Netty中的设计模式

本文深入剖析Netty框架中的设计模式应用,包括建造者模式、原型模式、责任链模式和模板方法模式。通过ServerBootstrap类展示建造者模式与原型模式结合使用,使对象构建更加灵活高效;ChannelPipeline和ChannelHandlerContext的实现揭示了责任链模式如何处理I/O请求;而SimpleChannelInboundHandler则体现了模板方法模式的优雅。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 建造者模式&原型模式

应用场景:

ServerBootstrap包含多个复杂子对象需要构建,对外仅暴露一个无参构造函数,通过多个建造函数去丰富对象。同时提供私有带参构造函数来构建复制对象,仅应用于clone方法中。

public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel> {
    private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class);
    private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap();
    private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap();
    private final ServerBootstrapConfig config = new ServerBootstrapConfig(this);
    private volatile EventLoopGroup childGroup;
    private volatile ChannelHandler childHandler;

    //唯一对外开放的无参构造函数
    public ServerBootstrap() {
    }
    
    //私有带参构造函数
    private ServerBootstrap(ServerBootstrap bootstrap) {
        super(bootstrap);
        this.childGroup = bootstrap.childGroup;
        this.childHandler = bootstrap.childHandler;
        synchronized(bootstrap.childOptions) {
            this.childOptions.putAll(bootstrap.childOptions);
        }

        synchronized(bootstrap.childAttrs) {
            this.childAttrs.putAll(bootstrap.childAttrs);
        }
    }
    //构建方法
    public ServerBootstrap group(EventLoopGroup group) {
        return this.group(group, group);
    }
    //构建方法
    public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (childGroup == null) {
            throw new NullPointerException("childGroup");
        } else if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        } else {
            this.childGroup = childGroup;
            return this;
        }
    }
    //构建方法
    public ServerBootstrap childHandler(ChannelHandler childHandler) {
        if (childHandler == null) {
            throw new NullPointerException("childHandler");
        } else {
            this.childHandler = childHandler;
            return this;
        }
    }
    //克隆方法,提供原型
    public ServerBootstrap clone() {
        return new ServerBootstrap(this);
    }
    ...
}

2 责任链

ChannelPipeline源码注释:可以说是一目了然!

 *                                                 I/O Request
 *                                            via {@link Channel} or
 *                                        {@link ChannelHandlerContext}
 *                                                      |
 *  +---------------------------------------------------+---------------+
 *  |                           ChannelPipeline         |               |
 *  |                                                  \|/              |
 *  |    +---------------------+            +-----------+----------+    |
 *  |    | Inbound Handler  N  |            | Outbound Handler  1  |    |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |              /|\                                  |               |
 *  |               |                                  \|/              |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |    | Inbound Handler N-1 |            | Outbound Handler  2  |    |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |              /|\                                  .               |
 *  |               .                                   .               |
 *  | ChannelHandlerContext.fireIN_EVT() ChannelHandlerContext.OUT_EVT()|
 *  |        [ method call]                       [method call]         |
 *  |               .                                   .               |
 *  |               .                                  \|/              |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |    | Inbound Handler  2  |            | Outbound Handler M-1 |    |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |              /|\                                  |               |
 *  |               |                                  \|/              |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |    | Inbound Handler  1  |            | Outbound Handler  M  |    |
 *  |    +----------+----------+            +-----------+----------+    |
 *  |              /|\                                  |               |
 *  +---------------+-----------------------------------+---------------+
 *                  |                                  \|/
 *  +---------------+-----------------------------------+---------------+
 *  |               |                                   |               |
 *  |       [ Socket.read() ]                    [ Socket.write() ]     |
 *  |                                                                   |
 *  |  Netty Internal I/O Threads (Transport Implementation)            |
 *  +-------------------------------------------------------------------+

ChannelHandlerContext:ChannelHandler的上下文,包含handler的执行环境信息,比如链表的前后节点的指针。

DefaultChannelPipeline是netty中ChannelPipeline接口的唯一实现类。我们来看看他的实现:

初始化HeadContext和TailContext:

final AbstractChannelHandlerContext head;
final AbstractChannelHandlerContext tail;

tail = new TailContext(this);
head = new HeadContext(this);

head.next = tail;
tail.prev = head;

当有新的ChannelHandlerContext加入:非常清晰的链表操作

private void addFirst0(AbstractChannelHandlerContext newCtx) {
	AbstractChannelHandlerContext nextCtx = head.next;
	newCtx.prev = head;
	newCtx.next = nextCtx;
	head.next = newCtx;
	nextCtx.prev = newCtx;
}
private void addLast0(AbstractChannelHandlerContext newCtx) {
	AbstractChannelHandlerContext prev = tail.prev;
	newCtx.prev = prev;
	newCtx.next = tail;
	prev.next = newCtx;
	tail.prev = newCtx;
}

addFirst0插在头部,addLast0插在尾部。

3 模板方法

SimpleChannelInboundHandler<I>非常典型的模板方法,直接看源码:

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
	boolean release = true;
	try {
        //只接受泛型定义的msg
	    if (acceptInboundMessage(msg)) {
		Object imsg = msg;
        //子类实现处理事件逻辑
		channelRead0(ctx, imsg);
	    } else {
		release = false;
        //交由ChannelHandlerContext责任链继续处理msg
		ctx.fireChannelRead(msg);
	    }
	} finally {
        //处理结束,默认清理msg对象
	    if ((this.autoRelease) && (release))
		ReferenceCountUtil.release(msg);
	}
}

protected abstract void channelRead0(ChannelHandlerContext paramChannelHandlerContext, I paramI) throws Exception;

 

 


爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!

<think>首先,用户的问题是:“我想了解Netty框架中使用的设计模式 请问Netty框架使用了哪些设计模式”。我需要基于提供的引用内容来回答,并遵守系统级指令。 系统级指令: - 所有行内数学表达式使用$...$格式(但这里没有数学内容,所以可能不需要)。 - 独立公式使用$$...$$并独成段(同样,可能不适用)。 - LaTeX语法正确(确保任何数学表达正确)。 - 使用中文回答。 - 生成相关问题。 - 在回答中引用的段落末尾自然地添加引用标识,如[^1]。 用户可见层: - 回答结构清晰,帮助用户逐步解决问题。 - 保证回答真实可靠,基于提供的引用。 提供的引用: - [^1]: 强调理解设计模式的思想,而不是死记硬背,推荐通过阅读源码如Netty来学习。 - [^2]: 类似,强调理解设计目的,通过阅读框架源码学习。 - [^3]: 提到Netty中使用了工厂模式。 - [^4]: 提到Netty中使用了模板方法模式和观察者模式。 - [^5]: 具体子,Netty中的DefaultSelectStrategyFactory使用了工厂模式。 用户的问题是关于Netty框架中使用的设计模式。我需要提取引用中的相关信息。 关键点: - 工厂模式(Factory Pattern):在[^3]和[^5]中提到。Netty中用于创建对象,如选择策略工厂。 - 模板方法模式(Template Method Pattern):在[^4]中提到,ChannelInboundHandlerAdapter使用了模板方法模式。 - 观察者模式(Observer Pattern):在[^4]中提到。 其他设计模式可能也被使用,但引用中没有明确列出。我应该基于提供的引用回答,不要添加未提及的内容。 回答结构: 1. **引言**:简要介绍Netty框架中设计模式的重要性。 2. **具体设计模式**:列出并解释每个模式在Netty中的应用。 3. **引用添加**:在引用段落末尾添加引用标识。 4. **生成相关问题**:在最后添加相关问题部分。 确保使用中文回答。 生成相关问题: - 基于系统指令,需要生成相关问题。如: - Netty中工厂模式的具体实现是怎样的? - 模板方法模式在Netty中如何应用? - 还有其他设计模式Netty中使用吗? 完整回答: - 先回答用户问题。 - 然后添加相关问题。 最终输出格式: - 回答部分。 - §§相关问题§§部分。</think>### Netty框架中使用的设计模式 Netty 是一个高性能、异步事件驱动的网络应用框架,广泛用于构建服务器和客户端。在 Netty 的设计中,设计模式被巧妙地应用,以提高代码的可扩展性、可维护性和灵活性。以下基于引用内容,总结 Netty 中主要使用的设计模式及其应用场景。设计模式的学习应注重理解其思想,而非死记硬背,通过阅读源码(如 Netty)能有效提升代码设计能力[^1][^2]。 #### 1. **工厂模式(Factory Pattern)** - **定义**:工厂模式是一种创建型设计模式,它定义一个用于创建对象的接口,但将实化的过程延迟到子类或具体实现类中,从而隐藏对象的创建细节[^3]。 - **在 Netty 中的应用**:Netty 使用工厂模式来创建策略对象或处理器实如,在事件循环组(EventLoopGroup)中,`DefaultSelectStrategyFactory` 负责创建选择策略对象(SelectStrategy)。这确保了策略的创建过程被封装,便于扩展和替换实现[^5]。 - 示代码片段(基于引用): ```java public final class DefaultSelectStrategyFactory implements SelectStrategyFactory { public static final SelectStrategyFactory INSTANCE = new DefaultSelectStrategyFactory(); private DefaultSelectStrategyFactory() { } @Override public SelectStrategy newSelectStrategy() { return DefaultSelectStrategy.INSTANCE; // 延迟创建策略对象 } } ``` - **优势**:提高了代码的灵活性和解耦,允许在不修改客户端代码的情况下更换策略实现[^3][^5]。 #### 2. **模板方法模式(Template Method Pattern)** - **定义**:模板方法模式是一种行为型设计模式,它定义一个算法骨架,将某些步骤延迟到子类实现,从而复用公共逻辑[^4]。 - **在 Netty 中的应用**:Netty 的处理器(Handler)设计中广泛使用此模式。如,`ChannelInboundHandlerAdapter` 类定义了一个模板方法 `channelRead`,其中包含公共逻辑(如解码),而具体处理步骤(如业务逻辑)由子类通过抽象方法 `onChannelRead` 实现[^4]。 - 示代码片段(基于引用): ```java public abstract class ChannelInboundHandlerAdapter extends ChannelHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { // 公共逻辑(如解码) onChannelRead(ctx, msg); // 调用子类实现的具体步骤 } protected abstract void onChannelRead(ChannelHandlerContext ctx, Object msg); } ``` - **优势**:简化了处理器开发,子类只需关注特定步骤,而公共逻辑(如错误处理)在父类中统一维护[^4]。 #### 3. **观察者模式(Observer Pattern)** - **定义**:观察者模式是一种行为型设计模式,它定义对象间的一对多依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动收到通知并更新[^4]。 - **在 Netty 中的应用**:Netty 的事件驱动模型核心就是观察者模式。如,`ChannelPipeline` 中的处理器(Handler)作为观察者,监听事件(如数据到达或连接关闭)。当事件发生时,`ChannelHandlerContext` 会通知所有注册的处理器,实现异步事件处理[^4]。 - **优势**:支持高并发和事件驱动架构,处理器可以动态添加或移除,增强了框架的扩展性[^4]。 ### 总结 Netty 框架通过上述设计模式(工厂模式、模板方法模式、观察者模式)实现了模块化、可扩展和高性能。这些模式的应用不仅提升了代码质量,还体现了设计模式的核心思想:解决特定问题(如对象创建、算法复用、事件通知)而非炫技[^2]。学习 Netty 源码是掌握设计模式的有效途径,建议结合实际项目或阅读 Spring、MyBatis 等框架源码加深理解[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qqchaozai

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值