Netty学习02之服务端启动流程分析
前言:不断学习就是程序员的宿命
上一篇:Netty学习01记录了Socket入门案例并对比Netty基本组件,这篇记录一下Netty基本组件。好记性不如烂笔头,沉淀记录下来自己才会心安。
一、Netty基本组件
①NioEventLoop:可以认为是Netty的“发动机”,它内部启动2种类型线程,其中一种用于监听客户端的连接,另一种处理客户端的读写。
②Channel:简单来说,就是对一个连接的封装,基于这个Channel进行数据读写
③Pipeline:数据读写可以认为一个逻辑处理链,这个逻辑处理链就叫Pipeline
④ChannelHandler:逻辑处理链中的每个逻辑对应的就是ChannelHandler
⑤ByteBuf:在一条Channel上数据流的读写都是基于ByteBuf缓冲区来操作
二、Netty服务端启动流程
Netty服务端启动流程
问题:
①服务端的socket在哪里初始化
②在哪里accept连接
1、创建服务端Channel
1.1 bind方法
1.2 initAndRegister()方法
通过ChannelFactory来获取Channel,实际是通过反射来获取Channel实例
这里的clazz指的就是我们在外部指定的NioServerSocketChannel.class(何以见得?)跟进这个工厂channelFactory是在哪里初始化的?
跟进channel方法,发现netty将我们指定的ChannelClass封装为ReflectiveChannelFactory,最后通过该channelFactory反射创建服务端Channel
1.2.1反射创建服务端Channel过程
①查看NioServerSocketChannel的构造方法,channelFactory通过反射创建Channel时会调用如下构造方法,进而调用newSocket()方法通过jdk底层来创建jdk底层Channel
跟进newSocket(),调用jdk底层方法来创建jdk底层Channel
② 再看NioServerSocketChannelConfig的创建(该配置类主要用于后续对该Channel的一些tcp底层参数相关的获取)
③调用父类构造函数AbstractNioChannel()
④调用AbstractChannel()构造方法(客户端与服务端Channel都继承此Channel)
至此、服务端Channel创建完成
2、服务端Channel初始化
服务端创建完Channel之后就会进行对其进行初始化,简单来说,保存用户自定义的属性,创建带有这些属性的连接接入器(特殊的ChannelHandler),连接接入器每次Accept新连接之后都会使用这些属性对新的连接做一些配置.
2.1 init()方法入口
2.2 设置用户自定义属性
创建连接接入器
3、注册Selector
init()方法入口,首先将当前NIO线程和当前Channel做绑定;调用register0()实际注册Selector,在这过程中做了3件事:①调用jdk底层注册,将当前Channel作为一个Attachment绑定到Selector上;接下来会连续触发2个事件(invokeHandlerAddedIfNeeded()、fireChannelRegitered()),通过这两个事件最终传播到用户的方法
1、register()方法入口
2、register0()方法
这里是实际注册Selector,主要包含以下3部分
2.1 doRegister()方法
2.2 invokeHandlerAddedIfNeeded()和fireChannelRegistered()方法
4、端口绑定