Netty启动流程服务端channel初始化源码分析

 更新时间:2022年03月25日 10:08:08   作者:向南是个万人迷  
这篇文章主要为大家介绍了Netty启动流程服务端channel初始化源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

前文传送门 Netty分布式server启动流程

服务端channel初始化

回顾上一小节initAndRegister()方法

final ChannelFuture initAndRegister() {
    Channel channel = null;
    try {
        //创建channel
        channel = channelFactory.newChannel();
        //初始化channel
        init(channel);
    } catch (Throwable t) {
        //忽略非关键代码
    }
    ChannelFuture regFuture = config().group().register(channel);
    //忽略非关键代码
    return regFuture;
}

简单回顾上一小节内容, 我们跟完了创建channel的步骤, 知道了Netty的NioServerSocketChannel和jdk的ServerSocketChannel之间的关系, NioServerSocketChannel和jdk的channel是组合关系, 在其父类AbstractChannel中有jdk的channel的一个成员变量, 通过创建netty的channel为jdk的channel赋值

init(Channel)方法

我们继续往下看init(Channel)方法

因为是ServerBootstrap对象调用的init()方法, 所以我们跟到ServerBootstrap类的init()方法中:

void init(Channel channel) throws Exception {
    //获取用户定义的选项(1)
    final Map<ChannelOption<?>, Object> options = options0();
    synchronized (options) {
        channel.config().setOptions(options);
    }

    //获取用户定义的属性(2)
    final Map<AttributeKey<?>, Object> attrs = attrs0();
    synchronized (attrs) {
        for (Entry<AttributeKey<?>, Object> e: attrs.entrySet()) {
            @SuppressWarnings("unchecked")
            AttributeKey<Object> key = (AttributeKey<Object>) e.getKey();
            channel.attr(key).set(e.getValue());
        }
    }
    //获取channel的pipline(3)
    ChannelPipeline p = channel.pipeline();
    //work线程组(4)
    final EventLoopGroup currentChildGroup = childGroup;
    //用户设置的Handler(5)
    final ChannelHandler currentChildHandler = childHandler;
    final Entry<ChannelOption<?>, Object>[] currentChildOptions;
    final Entry<AttributeKey<?>, Object>[] currentChildAttrs;
    //选项转化为Entry对象(6)
    synchronized (childOptions) { 
        currentChildOptions = childOptions.entrySet().toArray(newOptionArray(childOptions.size()));
    }
    //属性转化为Entry对象(7)
    synchronized (childAttrs) { 
        currentChildAttrs = childAttrs.entrySet().toArray(newAttrArray(childAttrs.size()));
    }
    //添加服务端handler(8)
    p.addLast(new ChannelInitializer<Channel>() {
        //初始化channel
        @Override
        public void initChannel(Channel ch) throws Exception {
            final ChannelPipeline pipeline = ch.pipeline();
            ChannelHandler handler = config.handler();
            if (handler != null) { 
                pipeline.addLast(handler);
            } 
            ch.eventLoop().execute(new Runnable() {
                @Override
                public void run() { 
                    pipeline.addLast(new ServerBootstrapAcceptor(
                            currentChildGroup, currentChildHandler, currentChildOptions, currentChildAttrs));
                }
            });
        }
    });
}

初看起来代码好长, 其实并不复杂, 这里对每一步进行一个简述:

步骤(1), (2)是获取的用户代码中定义的选项和属性

步骤(3)是获取channel的pipeline, 这个channel就是上一小节我们学习创建的NioServerSocketChannel, 我们知道每个channel都有个pipeline的属性, 是AbstractChannel的成员变量, 而这里的pipeline()就是获取其与channel绑定的pipeline, 这个pipline, 会在后面的章节中讲到

步骤(4)是获取worker线程组, 我们知道这个worker线程组就是在用户代码中创建的NioEventLoopGroup, 后来在ServerBootstrap的group()方法中赋值为ServerBootstrap的成员变量, 而这里是获取其成员变量, 并赋值到局部变量currentChildGroup中, NioEventLoop相关知识会在后面的章节讲到

步骤(6), (7)是将选项和属性转化成Entry对象

步骤(8)是添加服务端Handler, 是通过和channel绑定的pipeline调用addLast()方法进行添加, 传入一个ChannelInitializer类的子类对象, 至于addLast方法是做什么的, ChannelInitializer是做什么的, 后绪章节都会给大家详细剖析, 这里不必深究

这一小节我们了解了有关channel初始化的过程, 我们目前只需了解其大概步骤, 有关addLast的逻辑会在后面的章节进行详细剖析

以上就是Netty启动流程服务端channel初始化源码分析的详细内容,更多关于Netty启动流程服务端channel初始化的资料请关注脚本之家其它相关文章!

相关文章

  • MybatisPlus QueryWrapper常用方法实例

    MybatisPlus QueryWrapper常用方法实例

    MyBatis-Plus(opens new window)是一个MyBatis(opens new window)的增强工具,在 MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生,下面这篇文章主要给大家介绍了关于MybatisPlus QueryWrapper常用方法的相关资料,需要的朋友可以参考下
    2022-04-04
  • Java对数器验证算法详解

    Java对数器验证算法详解

    这篇文章主要介绍了Java对数器验证算法,Java对数函数的计算方法非常有问题,然而在API中却有惊人的误差。但是假如运用了以下的方法,用Java处理数字所碰到的小麻烦就可以轻而易举的解决了
    2023-04-04
  • Spring中@Primary注解的作用详解

    Spring中@Primary注解的作用详解

    这篇文章主要介绍了Spring中@Primary注解的作用详解,@Primary 注解是Spring框架中的一个注解,用于标识一个Bean作为默认的实现类,当存在多个实现类时,通过使用@Primary注解,可以指定其中一个作为默认的实现类,以便在注入时自动选择该实现类,需要的朋友可以参考下
    2023-10-10
  • java中乐观锁与悲观锁区别及使用场景分析

    java中乐观锁与悲观锁区别及使用场景分析

    本文主要介绍了java中乐观锁与悲观锁区别及使用场景分析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • Java9中对集合类扩展的of方法解析

    Java9中对集合类扩展的of方法解析

    这篇文章主要介绍了Java9 中对集合类扩展的of方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • java发送http get请求的两种方式

    java发送http get请求的两种方式

    这篇文章主要为大家详细介绍了java发送http get请求的两种方式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • 通过实例学习Spring @Required注释原理

    通过实例学习Spring @Required注释原理

    这篇文章主要介绍了通过实例学习Spring @Required注释原理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-03-03
  • Java多线程之ThreadLocal原理总结

    Java多线程之ThreadLocal原理总结

    这篇文章主要介绍了Java多线程ThreadLocal原理,同一个ThreadLocal所包含的对象,在不同的Thread中有不同的副本,文章中有详细的代码示例,需要的朋友参考一下
    2023-04-04
  • MyBatis之foreach标签的用法及多种循环问题

    MyBatis之foreach标签的用法及多种循环问题

    这篇文章主要介绍了MyBatis之foreach标签的用法及多种循环问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Mybatis插入Oracle数据库日期型数据过程解析

    Mybatis插入Oracle数据库日期型数据过程解析

    这篇文章主要介绍了Mybatis插入Oracle数据库日期型数据过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-09-09

最新评论