千家信息网

57. Netty源代码分析-服务器端启动ServerBootstrap初始化

发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,一. 开始1.1 上一篇接上一篇NioEventLoopGroup的实例化分析继续https://blog.51cto.com/483181/2118817这篇博客要分析的是 "2. ServerBo
千家信息网最后更新 2026年11月02日57. Netty源代码分析-服务器端启动ServerBootstrap初始化

一. 开始

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() {                    @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继承关系图

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 channelClass) {        return channelFactory(new ReflectiveChannelFactory(channelClass));    }public B channelFactory(ChannelFactory channelFactory) {        this.channelFactory = channelFactory;        return self();    }public class ReflectiveChannelFactory implements ChannelFactory {    private final Class clazz;    public ReflectiveChannelFactory(Class 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, Object> options; public  B option(ChannelOption 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的流程我们下篇继续分析。
方法 对象 类型 函数 分析 代码 属性 两个 工厂 模式 上一 不同 也就是 参数 变量 只是 场景 线程 肯定 服务 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 上海喔噻互联网科技有限公司 互联网和科技创新 互联网科技公司税收优惠 互联网巨头反垄断金融科技 深圳互联网科技公司 北京互联网科技有限公司 互联网金融科技委员会 中国互联网金融科技基金 无锡溥仪互联网科技有限公司 隆华科技工业互联网 茂名市互联网科技产业园 贵州叶脉互联网科技有限公司所属行业 崇明区互联网教育科技诚信经营 和信科技工业互联网 互联网金融科技公司的优势 上海钢联属于互联网科技股吗 领航科技大厦互联网公司 富国互联网金融科技混合基金 互联网科技手机排行榜 10位科技互联网大佬 天津市摩尔互联网科技 互联网科技的 互联网 科技创业 深圳艾佳互联网科技 科技伦理 互联网公司 互联网之后的科技是什么 滨湖区互联网智能科技产品有哪些 山东有哪些互联网科技公司 厦门江牛科技互联网 保山互联网科技靠谱吗
0