91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

57. Netty源代碼分析-服務器端啟動ServerBootstrap初始化

發布時間:2020-07-08 13:39:14 來源:網絡 閱讀:1296 作者:rongwei84n 欄目:軟件技術

一. 開始

1.1 上一篇

接上一篇NioEventLoopGroup的實例化分析繼續
https://blog.51cto.com/483181/2118817

這篇博客要分析的是 “2. ServerBootstrap初始化”,如下:

EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap(); //2. ServerBootstrap初始化
            b.group(bossGroup, workerGroup) // 2. ServerBootstrap初始化
                .channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_BACKLOG, 100)
                .handler(new LoggingHandler(LogLevel.INFO))
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {

                    }
                });

            ChannelFuture f = b.bind(port).sync(); //3. bind
            f.channel().closeFuture().sync();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

二. ServerBootstrap

2.1 ServerBootstrap繼承關系圖

57. Netty源代碼分析-服務器端啟動ServerBootstrap初始化

2.2 ServerBootstrap構造函數

public ServerBootstrap() { }

ServerBootstrap提供了一個無參構造函數,其實有點奇怪,因為像這種網絡服務肯定要適應不同的場景,所以肯定得有很多參數的構造函數。
對于這一點,正是因為要適配的參數太多了,所以ServerBootstrap提供了一個無參構造函數,然后使用構造者模式來解決這個問題。
如下:

public ServerBootstrap childHandler(ChannelHandler childHandler) {
        if (childHandler == null) {
            throw new NullPointerException("childHandler");
        }
        this.childHandler = childHandler;
        return this;
    }

2.3 ServerBootstrap.group

public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
        super.group(parentGroup);
        if (childGroup == null) {
            throw new NullPointerException("childGroup");
        }
        if (this.childGroup != null) {
            throw new IllegalStateException("childGroup set already");
        }
        this.childGroup = childGroup;
        return this;
    }

父類的group(xx)

public B group(EventLoopGroup group) {
        this.group = group;
        return self();
    }

傳入了兩個EventLoopGroup,也就是上一篇文章說的NioEventLoopGroup,一個是bossGroup,一個workerGroup.
其中bossGroup存在它的父類group屬性
workerGroup存在ServerBootstrap的childGroup屬性里面,不過暫時不知道它們之間的區別。

繼續看b.channel(NioServerSocketChannel.class)

2.4 設置channel

代碼在ServerBootstrap的父類AbstractBootstrap里面,如下:

public B channel(Class<? extends C> channelClass) {
        return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
    }

public B channelFactory(ChannelFactory<? extends C> channelFactory) {
        this.channelFactory = channelFactory;
        return self();
    }

public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {

    private final Class<? extends T> clazz;

    public ReflectiveChannelFactory(Class<? extends T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T newChannel() {
        try {
            return clazz.getConstructor().newInstance();
        } catch (Throwable t) {
        }
    }
}               

上面這段代碼可以看出:

  1. 初始化了一個ReflectiveChannelFactory工程類,它是一個工廠類,調用newChannel的時候負責初始化一個指定Channel。也就是我們傳入進來的NioServerSocketChannel對象。
  2. 這個工廠對象保存在AbstractBootstrap的channelFactory屬性里面,以便于后面調用生成channel對象,目前只是保存工廠對象。

繼續看b.option()方法

2.5 設置option

Map<ChannelOption<?>, Object> options; 

public <T> B option(ChannelOption<T> option, T value) {
        if (option == null) {
            throw new NullPointerException("option");
        }
        if (value == null) {
            synchronized (options) {
                options.remove(option);
            }
        } else {
            synchronized (options) {
                options.put(option, value);
            }
        }
        return self();
    }

從上面這代碼可以看出幾點:
1.option方法帶有remove和put兩個操作,根據value是否null來判斷。這種寫法自己以前用的比較少,一般的話會提供兩個方法出來。
2.如果是put的話,那么把值存在options這個Map集合里面。

繼續回頭看b.handler()方法

2.6 handler方法

handler方法位于ServerBootstrap的父類AbstractBootstrap里面,如下:

private volatile ChannelHandler handler;

public B handler(ChannelHandler handler) {
        if (handler == null) {
            throw new NullPointerException("handler");
        }
        this.handler = handler;
        return self();
    }

很是簡單,就是把傳入的ChannelHandler對象保存起來,放在屬性handler里面。
另外,注意到handler對象是volatile類型的,volatile具有揮發性,如果一個線程修改了數據,那么另外一個線程可以馬上看到這個修改。具體大家可以百度下。

繼續回去看b.childHandler(xx)方法

2.7 childHandler

childHandler方法位于ServerBootstrap里面

private volatile ChannelHandler childHandler;

public ServerBootstrap childHandler(ChannelHandler childHandler) {

                private volatile ChannelHandler childHandler;

        if (childHandler == null) {
            throw new NullPointerException("childHandler");
        }
        this.childHandler = childHandler;
        return this;
    }

從上面代碼可以看出:

  1. childHandler保存在ServerBootstrap,變量是childHandler,當然也是volatile類型的,我們傳進來的類型是 ChannelInitializer,重寫了它的initChannel方法。
  2. childHandler和handler都是ChannelHandler類型,不過一個在子類,一個在父類里面。

三. 總結

ServerBootstrap的初始化分析完之后,我們來總結下。

  1. ServerBootstrap提供了一個無參構造函數,為了適應各種不同的場景。 它使用了構造者模式,構造者模式大家百度即可,比如: https://www.cnblogs.com/cc11001100/p/5939220.html

  2. ServerBootstrap保存了
    EventLoopGroup childGroup,在上面例子我們的類型是NioEventLoopGroup
    ChannelHandler childHandler;

  3. 父類AbstractBootstrap保存了同一個類型的
    volatile EventLoopGroup group;
    private volatile ChannelHandler handler;

  4. 到目前為止,我們只是初始化了所有的變量,為下一步bind做準備。bind的流程我們下篇繼續分析。
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

乌兰浩特市| 建平县| 榆社县| 汉川市| 张家港市| 康马县| 于都县| 盐源县| 平罗县| 林口县| 孝感市| 遂宁市| 眉山市| 葵青区| 凌源市| 杭锦旗| 江阴市| 苍南县| 普兰店市| 屏东县| 梁河县| 渭源县| 罗山县| 阜阳市| 泸定县| 昆山市| 新营市| 灵璧县| 邛崃市| 开原市| 威信县| 洛宁县| 高雄县| 朝阳县| 广昌县| 六盘水市| 临漳县| 滨海县| 桂东县| 天等县| 金堂县|