Netty Channel 详解

优质博文:IT-BLOG-CN

一、Netty 服务端启动过程

【1】创建服务端Channel
【2】初始化服务端Channel
【3】注册Selector
【4】端口绑定:我们分析源码的入口从端口绑定开始,ServerBootstrapbind(int inetPort)方法,实际上是AbstractBootstrapbind(int inetPort)方法。ServerBootstrap继承了AbstractBootstrap

二、分析服务端创建Channel的过程

【1】bind()【分析入口,端口绑定】在bind()方法中,有一个doBind()方法,处理端口绑定:

public ChannelFuture bind(SocketAddress localAddress) {
   
    validate();
    if (localAddress == null) {
   
        throw new NullPointerException("localAddress");
    }
    return doBind(localAddress);// 实际绑定
}

【2】在doBind()方法中,调用initAndRegister来处理初始化和注册:

private ChannelFuture doBind(final SocketAddress localAddress) {
   
    final ChannelFuture regFuture = initAndRegister();// 初始化与注册
    // ...
}

【3】initAndRegister()【初始化并注册】进入initAndRegister()方法里面,发现是调用了channelFactory(Channel工厂) 的newChannel()来创建channel

final ChannelFuture initAndRegister() {
   
    Channel channel = null;
    try {
   
        channel = channelFactory.newChannel();// channelFactory创建Channel
        init(channel);
    }
    //...
}

【4】newChannel()【创建服务端channel】进去newChannel()方法,就能看到,实际上是通过反射Class.newInstance()来创建Channel对象的:

public T newChannel() {
   
    try {
   
        return clazz.newInstance();// Channel工厂通过反射,来创建Channel
    } catch (Throwable t) {
   
        throw new ChannelException("Unable to create Channel from class " + clazz, t);
    }
}

那么,这个class到底是啥呢,什么时候传递进来的?

【5】ChannelFactory的初始化:【接收服务端ChannelClass,通过反射生成Channel】还记得之前我们的第一个Demo里面有一个channel()方法,我们传递了一个参数NioServerSocketChannel.class

ServerBootstrap serverBoot = new ServerBootstrap();
serverBoot.group(bossGroup,workGroup)
        .channel(NioServerSocketChannel.class)// 设置服务端Channel
        //...
);

进去channel()方法中:

public B channel(Class<? extends C> channelClass) {
   
    if (channelClass == null) {
   
        throw new NullPointerException("channelClass");
    }
    return channelFactory(new ReflectiveChannelFactory<C>
        (channelClass));// 传递class给ChannelFactory的构造方法
}

然后,我们进去ChannelFactory的构造方法里面:

public ReflectiveChannelFactory(Class<? extends T> clazz) {
   
    if (clazz == null) {
   
        throw new NullPointerException("clazz");
    }
    this.clazz = clazz;// 接收传递进来的Channel的Class
}
@Override
public T newChannel() {
   
    try {
   
        return clazz.newInstance();// 通过Channel的Class反射生成Channel对象
    } catch (Throwable t) {
   
        throw new ChannelException("Unable to create Channel from class " + clazz, t);
    }
}

到此,Channel的创建过程就出来了,一句话总结就是:通过我们在ServerBootstrapchannel(clazz)方法里面设置的Class,通过Java反射,Class.newInstance来生成最终的Channel对象。

相关推荐

  1. Hive-DDL详解(超详细

    2024-01-12 21:42:03       34 阅读
  2. Hive-DML详解(超详细

    2024-01-12 21:42:03       29 阅读
  3. super详解

    2024-01-12 21:42:03       35 阅读
  4. scheduleatfixedrate详解

    2024-01-12 21:42:03       40 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-12 21:42:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-12 21:42:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-12 21:42:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-12 21:42:03       20 阅读

热门阅读

  1. 代码随想录算法训练营Day24|77. 组合

    2024-01-12 21:42:03       38 阅读
  2. ClickHouse中JOIN算法选择逻辑以及auto选项

    2024-01-12 21:42:03       30 阅读
  3. python之异常与日志

    2024-01-12 21:42:03       37 阅读
  4. 职工工作量统计(课程设计)

    2024-01-12 21:42:03       32 阅读
  5. Go语言中Print Printf Println的区别

    2024-01-12 21:42:03       33 阅读
  6. SQL语句

    SQL语句

    2024-01-12 21:42:03      35 阅读
  7. 在vue中使用v-for遍历arco.design图标

    2024-01-12 21:42:03       35 阅读
  8. ant-design-vue的table组件的自定义表头和表格内容

    2024-01-12 21:42:03       37 阅读
  9. flask web学习之模板(二)

    2024-01-12 21:42:03       32 阅读
  10. 原型和原型链

    2024-01-12 21:42:03       34 阅读
  11. [渗透测试学习] Crocodile - HackTheBox

    2024-01-12 21:42:03       36 阅读
  12. linux 安装redis

    2024-01-12 21:42:03       39 阅读
  13. [DM8] 查看当前执行的查询并杀死

    2024-01-12 21:42:03       37 阅读
  14. Postman应用打开超级慢解决办法

    2024-01-12 21:42:03       33 阅读