分類
發燒車訊

Netty源碼學習系列之3-ServerBootstrap的初始化_網頁設計公司

※如何讓商品強力曝光呢? 網頁設計公司幫您建置最吸引人的網站,提高曝光率!

以設計的實用美學觀點,規劃出舒適、美觀的視覺畫面,有效提昇使用者的心理期待,營造出輕鬆、愉悅的網站瀏覽體驗。

前言

    根據前文我們知道,NioEventLoopGroup和NioEventLoop是netty對Reactor線程模型的實現,而本文要說的ServerBootstrap是對上面二者的整合與調用,是一個統籌者和協調者。具體netty使用的是Reactor單線程模型還是多線程模型、抑或者主從多線程模型,都是ServerBootstrap的不同配置決定的。

    下面照例粘貼一下示例demo(以Reactor多線程模式構建),開始正文。

 1 public class NettyDemo1 {
 2     // netty服務端的一般性寫法
 3     public static void main(String[] args) {
 4         EventLoopGroup boss = new NioEventLoopGroup(1);
 5         EventLoopGroup worker = new NioEventLoopGroup();
 6         try {
 7             ServerBootstrap bootstrap = new ServerBootstrap();
 8             bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
 9                     .option(ChannelOption.SO_BACKLOG, 100)
10                     .childHandler(new ChannelInitializer<SocketChannel>() {
11                         @Override
12                         protected void initChannel(SocketChannel socketChannel) throws Exception {
13                             ChannelPipeline pipeline = socketChannel.pipeline();
14                             pipeline.addLast(new StringDecoder());
15                             pipeline.addLast(new StringEncoder());
16                             pipeline.addLast(new NettyServerHandler());
17                         }
18                     });
19             ChannelFuture channelFuture = bootstrap.bind(90);
20             channelFuture.channel().closeFuture().sync();
21         } catch (Exception e) {
22             e.printStackTrace();
23         } finally {
24             boss.shutdownGracefully();
25             worker.shutdownGracefully();
26         }
27     }
28 }

 

一、ServerBootstrap的初始化

    ServerBootstrap的無參構造器啥都沒做,它使用的build模式給屬性賦值,即上面示例中看到的,每執行一個賦值方法都會返回當前對象的引用使得可以繼續鏈式調用。下面挨個方法追蹤。

1 public ServerBootstrap() { }

 

1、ServerBootstrap.group方法

    ServerBootstrap有兩個可用重載group方法(如下的兩個),其中接收一個group入參的方法會調用有兩個入參的group方法,只是兩個參數傳同一個group。這兩個group方法決定了netty使用的Reactor線程模型的類型,一個group入參的方法對應Reactor單線程模型,兩個入參且不是同一個group的方法對應Reactor多線程模型或主從多線程模型(具體是哪一種取決於實例化parentGroup時的線程數)。此處只是提一下,先有個印象,後面會對線程模型進行詳細研究。

1 public ServerBootstrap group(EventLoopGroup group) {
2         return group(group, group);
3     }
1 public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
2         super.group(parentGroup);
3         ObjectUtil.checkNotNull(childGroup, "childGroup");
4         if (this.childGroup != null) {
5             throw new IllegalStateException("childGroup set already");
6         }
7         this.childGroup = childGroup;
8         return this;
9     }

    可以看到上述group方法對兩個入參進行了不同位置的賦值,將第一個參數parentGroup傳給了父類AbstractBootstrap的group方法,如下,即最終賦值給了AbstractBootstrap中的group屬性。第二個參數直接賦值給了ServerBootstrap的childGroup屬性。

1 public B group(EventLoopGroup group) {
2         ObjectUtil.checkNotNull(group, "group");
3         if (this.group != null) {
4             throw new IllegalStateException("group set already");
5         }
6         this.group = group;
7         return self();
8     }

 

2、ServerBootstrap.option/childOption方法和ServerBootstrap.attr/childAttr方法

    這四個方法只是做了屬性的賦值,分別賦值給了AbstractBootstrap的options屬性和attrs屬性以及ServerBootstrap的childOptions屬性和childAttrs屬性。

 1 public <T> B option(ChannelOption<T> option, T value) {
 2         ObjectUtil.checkNotNull(option, "option");
 3         if (value == null) {
 4             synchronized (options) {
 5                 options.remove(option);
 6             }
 7         } else {
 8             synchronized (options) {
 9                 options.put(option, value);
10             }
11         }
12         return self();
13     }
 1 public <T> B attr(AttributeKey<T> key, T value) {
 2         ObjectUtil.checkNotNull(key, "key");
 3         if (value == null) {
 4             synchronized (attrs) {
 5                 attrs.remove(key);
 6             }
 7         } else {
 8             synchronized (attrs) {
 9                 attrs.put(key, value);
10             }
11         }
12         return self();
13     }

 

※綠能、環保無空污,成為電動車最新代名詞,目前市場使用率逐漸普及化

台中景泰電動車行只是一個單純的理由,將來台灣的環境,出門可以自由放心的深呼吸,讓空氣回歸自然的乾淨,減少污染,留給我們下一代有好品質無空污的優質環境

3、ServerBootstrap.channel方法

    調用的是父類AbstractBootstrap的channel方法:

1 public B channel(Class<? extends C> channelClass) {
2         return channelFactory(new ReflectiveChannelFactory<C>(
3                 ObjectUtil.checkNotNull(channelClass, "channelClass")
4         ));
5     }

    可以看到先封裝成了一個ReflectiveChannelFactory對象,然後調用channelFactory方法,下面挨個看。ReflectiveChannelFactory的構造器如下,可見就是將傳入class對象的構造器取出來賦值,此時constructor存放的就是NioServerSocketChannel的構造器。

public ReflectiveChannelFactory(Class<? extends T> clazz) {
        ObjectUtil.checkNotNull(clazz, "clazz");
        try {
            this.constructor = clazz.getConstructor();
        } catch (NoSuchMethodException e) {
            throw new IllegalArgumentException("Class " + StringUtil.simpleClassName(clazz) +
                    " does not have a public non-arg constructor", e);
        }
    }

    channelFactory方法的工作是將上面創建的ReflectiveChannelFactory對象賦值給AbstractBootstrap的channelFactory屬性:

1 public B channelFactory(ChannelFactory<? extends C> channelFactory) {
2         ObjectUtil.checkNotNull(channelFactory, "channelFactory");
3         if (this.channelFactory != null) {
4             throw new IllegalStateException("channelFactory set already");
5         }
6 
7         this.channelFactory = channelFactory;
8         return self();
9     }

 

4、ServerBootstrap.handler方法和ServerBootstrap.childHandler方法

    handler方法的入參賦值給了AbstractBootstrap的handler屬性,childHandler方法的入參賦值給了ServerBootstrap的childHandler屬性。看到這裏想必園友們也能看出ServerBootstrap的賦值規律了,凡是child開頭的都放在ServerBootstrap中,而不帶child的大多放在其父類ABstractBootstrap中。

1 public B handler(ChannelHandler handler) {
2         this.handler = ObjectUtil.checkNotNull(handler, "handler");
3         return self();
4     }
1 public ServerBootstrap childHandler(ChannelHandler childHandler) {
2         this.childHandler = ObjectUtil.checkNotNull(childHandler, "childHandler");
3         return this;
4     }

 

5、完成賦值后ServerBootstrap的快照圖

 

 

小結

    ServerBootstrap的初始化過程看起來賦了很多值,但都只是做了準備工作,看起來輕鬆又簡單,但請注意,這是暴風雨前寧靜。前面的各種賦值到底有什麼用處?很多屬性分為有child前綴和沒有child前綴,這樣設置又有什麼意圖?下一期將進入ServerBootstrap的bind方法,這是netty的深水區,很多謎底也將在這裏得到揭曉,敬請期待!

 

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

網站的第一印象網頁設計,決定了客戶是否繼續瀏覽的意願。台北網動廣告製作的RWD網頁設計,採用精簡與質感的CSS語法,提升企業的專業形象與簡約舒適的瀏覽體驗,讓瀏覽者第一眼就愛上它。