好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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

服务端channel初始化

回顾上一小节initAndRegister()方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

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()方法中:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

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初始化的资料请关注其它相关文章!

原文链接:https://HdhCmsTestcnblogs测试数据/xiangnan6122/p/10202646.html

查看更多关于Netty启动流程服务端channel初始化源码分析的详细内容...

  阅读:12次