诺禾-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() {
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 B option(ChannelOption 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 B attr(AttributeKey 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(
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的深水区,很多谜底也将在这里得到揭晓,敬请等待!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值