浅析(1)Builder 构建者模式
为了解决参数较多的问题,这里 netty ServerBootstrap 使用了 builder 模式,可以大大降低我们的配置量,也可以灵活指定配置 。
(2)EventLoopGroup 线程池
为了提升性能,线程池是一个自然的选择 。
(3)设置并且绑定 channel
可以发现我们源码中只有一句话 channel(NioServerSocketChannel.class)
这个方法源码如下:
public B channel(Class<? extends C> channelClass) { if (channelClass == null) { throw new NullPointerException("channelClass"); } return channelFactory(new ReflectiveChannelFactory<C>(channelClass));}很显然,这里使用了工厂模式 。
我们只需要简单的指定 class 信息,netty 会自动通过反射创建对应的实现类 。
(4)初始化 ChannelPipeline
流水线使用了责任链模式,用于处理一系列的 ChannelHandler 。
(5)添加 ChannelHandler
netty 这里的 initChannel 方法,可以让我们非常方便的添加 ChannelHandler 。
对个人的影响也比较大,我写的很多工具方法也会采用类似的模式 。
(6)绑定并且启动监听端口
我们使用时只有非常优雅的一句话 ChannelFuture f = b.bind(port).sync();,实际上 netty 为我们做了一些封装:
虽然我们只指定了 port,本质上肯定还是 socket 地址,只不过默认 ip 为本地而已 。
public ChannelFuture bind(SocketAddress localAddress) { validate(); if (localAddress == null) { throw new NullPointerException("localAddress"); } return doBind(localAddress);}doBind 的实现还是比较多的,暂时不做展开 。
(7)selector 轮训 & 触发
写过 JAVA nio 的小伙伴们肯定知道,需要通过 selector 轮训获取消息 。
实际上 netty 将这些细节封装了起来 。轮训准备就绪 Channel 之后,将由 Reactor 线程 NioEventLoop 执行 ChannelPipeline 的响应方法,最终调用到 ChannelHandler 。
ChannelHandler 中包含了系统内置的处理类,和用户自定义的处理类 。

文章插图
源码解析每一个版本的源码可能有差异,这里老马的版本是 4.1.17.Final 。
EventLoopGroupEventLoopGroup 就是 Reactor 线程池 。
group 方法如下:
/** * Set the {@link EventLoopGroup} for the parent (acceptor) and the child (client). These * {@link EventLoopGroup}'s are used to handle all the events and IO for {@link ServerChannel} and * {@link Channel}'s. */public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) { super.group(parentGroup); if (childGroup == null) { throw new NullPointerException("childGroup"); } if (this.childGroup != null) { throw new IllegalStateException("childGroup set already"); } this.childGroup = childGroup; return this;}这里调用了父类的方法 super.group(parentGroup);,实现如下:/** * The {@link EventLoopGroup} which is used to handle all the events for the to-be-created * {@link Channel} */public B group(EventLoopGroup group) { if (group == null) { throw new NullPointerException("group"); } if (this.group != null) { throw new IllegalStateException("group set already"); } this.group = group; return self();}这个方法主要用于设置 IO 线程,执行和调度网络事件的读写 。channelchannel 的方法如下:
【netty 服务端启动流程源码详解】
推荐阅读
- Netty 实战:如何实现文件服务器?
- Netty 实战:如何实现 HTTP 服务器?
- 什么是2021年最佳的后端开发框架
- 如何实现几百台SIP终端实现自动化部署
- 如何在 Linux 终端查看图像
- 浅谈linux下基于UDP服务的负载均衡方法
- 粽子是端午节的必备食物据说在春秋时期 关于端午粽子的由来
- 端午节五彩线的颜色 端午节绑五色线的意义
- 驱五毒是什么节日 端午节的五毒有哪些
- 课后服务申请理由怎么写?
