Netty源码分析(一):服务端启动

Netty服务端启动的四个过程
1.创建服务端Channel
2.初始化服务端Channel
3.注册到Selector
4.端口绑定

创建服务端Channel

创建服务端Channel的步骤:
在这里插入图片描述

  • 通过bind方法追踪代码,如下:
    在这里插入图片描述
    可以看到下面的代码:
    在这里插入图片描述
    追踪进去可以看到:
    在这里插入图片描述
    在这里插入图片描述
    看看该方法是怎样创建管道的
    在这里插入图片描述

  • 这个clazz是哪个类?
    在利用辅助类进行配置信息的时候,我们传入了一个类,这个类就是我们配置信息传入的那个类
    在这里插入图片描述
    追踪一下:
    在这里插入图片描述
    在这里插入图片描述
    这就是clazz的赋值情况

  • 传入的NioSocketChannel是一个什么样的类?创建的细节是什么?
    在这里插入图片描述
    先来看四个类的继承关系以及在创建过程中的作用(顶层为父类,往下为子类)
    AbstractChannel:(3).创建id,unsafe,pipline
              |
    AbstractNioChannel:(2).设置非阻塞:configureBlocking(false)
              |
    AbstractNioMessageChannel:
              |
    NioSocketChannel:(1).newSocket()方法调用JDK底层代码创建ServerSokcetChannel
    创建tcp配置类NioServerSocketChannelConfig

  • 现在来看看为什么反射创建了NioSocketChannel创建了Channel了呢
    先来看NioSocketChannel的构造函数做了什么
    在这里插入图片描述
    该构造函数调用了其他构造函数,传参是newSocket()方法的返回,看看newSocket()方法
    在这里插入图片描述
    这块代码就是调用JDK代码来创建Channel了,可以看到返回值是ServerSocketChannel,这个在NIO中比较熟悉了。
    看一下被调用的构造函数
    在这里插入图片描述
    同时创建了TCP配置类NioServerSocketChannelConfig,这些就是括号(1)
    下面跟随super进入上上一级父类AbstractNioChannel
    在这里插入图片描述
    可以看到NIO编程中的设置非阻塞模式,也就是括号(2)
    继续跟踪父类AbstractChannel
    在这里插入图片描述
    这里创建了id,unsage,pipeline,也就是(3)

初始化服务端Channel

在这里插入图片描述
重点关注init()方法
在这里插入图片描述

  • 四个步骤:
    (1)set ChannelOptions,ChannelAttrs
    在这里插入图片描述
    (2)set ChildOptions,set ChildAttrs(还是在init方法中)
    在这里插入图片描述
    (3)配置pipeline
    在这里插入图片描述
    拿到pipeline后将用户添加的handler添加到该pipeline上
    (4)在最后默认添加ServerBootstrapAcceptor(一个特殊的ChannelHandler)
    在这里插入图片描述
  • ServerBootstrapAcceptor是一个新连接接入器,构造的参数都是配置信息中所传入的信息
    来看看这四个参数
    在这里插入图片描述
    跟踪出处
    在这里插入图片描述
    这是ServerBootstrap中的两个属性直接赋值过来的,而这两个属性就是在写代码时配置信息所配置的信息
    在这里插入图片描述
    分别点入用户代码的这两个方法
    先点入group方法
    在这里插入图片描述
    可以看到childGroup是传入的参数
    再跟踪childHandler
    在这里插入图片描述
    childHandler也是传入的
    剩下的两个属性就是刚才初始化的两个属性
    在这里插入图片描述

注册到selector上

同样是initAndRegister()方法
在这里插入图片描述
创建并且完成初始化后,就会调用register方法
register方法的结构图
在这里插入图片描述
所以注册到选择器需要重点关注register方法
这里留一个问题:
为什么追踪register方法追踪到的是EventLoopGroup,但是讲解这块展示的逻辑代码是AbstractChannel

  • 看下register方法
    在这里插入图片描述
    追踪register0
    在这里插入图片描述
    追踪doRegister方法,查看真正注册的方法内容
    在这里插入图片描述
    下面看一下invokeHandlerAddedIfNeeded和fireChannelRegistered两个方法
    在这里插入图片描述
    这两个方法分别对应于Handler中的两个继承方法,如下:
    在这里插入图片描述

  • 最后看一下fireChannelActive方法,该方法不会被调用
    在这里插入图片描述
    因为netty在这里只是进行了selector绑定的操作,并没有进行端口的绑定的操作。所以isActive方法会返回false

服务端口的绑定

方法结构图
在这里插入图片描述

  • 还是从doBind方法开始看,如下:
    在这里插入图片描述
    追踪doBind0方法
    有一个问题:为什么追踪后是AbstractBootstrap的方法,但是讲解内容确是AbstarctChannel
    下面看一下AbstractChannel的bind方法
    在这里插入图片描述
    doBind方法
    在这里插入图片描述
    bind方法调用了JDK底层的bind方法,javaChannel返回开始通过JDK底层创建的Channel
    在这里真正完成了端口的绑定

  • 下面看一段逻辑
    在这里插入图片描述
    这就调用了pipeline的fireChannelActive方法,也是一个传播事件,在初始化的时候当时没有调用这个fireChannelActive方法,所以在这里绑定完端口以后才调用。

关于后面为什么讲解又到了chnnelActive方法,而又调用了什么Autoread方法,这个不是很懂。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值