为了账号安全,请及时绑定邮箱和手机立即绑定

【Netty】(4)—源码AbstractBootstrap

标签:
Java

一、概念

AbstractBootstrap是一个工具类,用于服务器通道的一系列配置,绑定NioEventLoopGroup线程组,指定指定NIO的模式,指定子处理器,用于处理workerGroup,指定端口等。

5c1a74a50001575609100488.jpg

通过类图我们知道AbstractBootstrap类是ServerBootstrap及Bootstrap的基类。

总的来说可以总结

1、提供了一个ChannelFactory对象用来创建Channel,一个Channel会对应一个EventLoop用于IO的事件处理,在一个Channel的整个生命周期中
  只会绑定一个EventLoop,这里可理解给Channel分配一个线程进行IO事件处理,结束后回收该线程。2、AbstractBootstrap没有提供EventLoop而是提供了一个EventLoopGroup,上篇博客讲过EventLoopGroup对象就是一个含有EventLoop的数组。
   但是当一个连接到达,Netty会注册一个Channel,然后EventLoopGroup会分配一个EventLoop绑定到这个channel。3、不管是服务器还是客户端的Channel都需要绑定一个本地端口这就有了SocketAddress类的对象localAddress。4、Channel有很多选项所有有了options对象LinkedHashMap<channeloption<?>, Object>5、怎么处理Channel的IO事件呢,我们添加一个事件处理器ChannelHandler对象。


二、源码

这里只是部分AbstractBootstrap源码,具体可以通过ServerBootstrap或者Bootstrap点进去后,查看父类。

public abstract class AbstractBootstrap<B extends io.netty.bootstrap.AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {    /**
     * 这里的EventLoopGroup 作为服务端 Acceptor 线程,负责处理客户端的请求接入
     * 作为客户端 Connector 线程,负责注册监听连接操作位,用于判断异步连接结果。
     */
    volatile EventLoopGroup group;    /**
     * 创建Channer 工厂 根据传入的类型来创建不同的Channer 
     * 比如服务器传入的是:NioServerSocketChannel.class
     * 客户端传入:NioSocketChannel.class 。 加上这个注解代表这个已经过期有更好的替代类
     */
    @SuppressWarnings("deprecation")    private volatile ChannelFactory<? extends C> channelFactory;    /**
     * SocketAddress 是用来绑定一个服务端口 用的
     */
    private volatile SocketAddress localAddress;    /**
     * ChannelOption 可以添加Channer 添加一些配置信息
     */
    private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();    private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();    /**
     * ChannelHandler 是具体怎么处理Channer 的IO事件。
     */
    private volatile ChannelHandler handler;    /**
     * 传入一个EventLoopGroup,不管服务端还是客户端都会调用该方法
     */
    public B group(EventLoopGroup group) {        if (group == null) {            throw new NullPointerException("group");
        }        if (this.group != null) {            throw new IllegalStateException("group set already");
        }        this.group = group;        return self();
    }    /**
     * 返回对象本身
     */
    @SuppressWarnings("unchecked")    private B self() {        return (B) this;
    }    /**
     *设置服务端的Channel,Netty通过Channel工厂类创建不同的Channel。
     * 对于服务端传入:Netty需要创建NioServerSocketChannel
     * 对于客户端传入:NioSocketChannel.class
     */
    public B channel(Class<? extends C> channelClass) {        if (channelClass == null) {            throw new NullPointerException("channelClass");
        }        return channelFactory(new ReflectiveChannelFactory<C>(channelClass));
    }    /**
     * 创建好Channel后,返回对象本身
     */
    @Deprecated
    public B channelFactory(ChannelFactory<? extends C> channelFactory) {        if (channelFactory == null) {            throw new NullPointerException("channelFactory");
        }        if (this.channelFactory != null) {            throw new IllegalStateException("channelFactory set already");
        }        this.channelFactory = channelFactory;        return self();
    }    /**
     * 设置一些Channel相关参数
     */
    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();
    }    /**
     *  服务端方法: 绑定端口 对该端口进行监听
     */
    public ChannelFuture bind(int inetPort) {        return bind(new InetSocketAddress(inetPort));
    }    /**
     * 客户端方法: 需要传入访问的地址和端口
     */
    public ChannelFuture bind(String inetHost, int inetPort) {        return bind(SocketUtils.socketAddress(inetHost, inetPort));
    }    public ChannelFuture bind(SocketAddress localAddress) {        if (localAddress == null) {            throw new NullPointerException("localAddress");
        }        //这个方法这里省略调,具体可以看源码
        return doBind(localAddress);
    }    /**
     * 设置父类的Handler,父类的handler是客户端新接入的接连SocketChannel对应的ChannelPipeline 的handler
     */
    public B handler(ChannelHandler handler) {        if (handler == null) {            throw new NullPointerException("handler");
        }        this.handler = handler;        return self();
    }
}

这里并没有很深入的去了解AbstractBootstrap,写这个就是为接下来写ServerBootstrap及Bootstrap做一个小小的铺垫吧。
以上源码只是个人的理解,如有不对希望能够留言指点。万分感谢!

原文出处:https://www.cnblogs.com/qdhxhz/p/10092919.html  

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消