文章目录
- 前言
- 一、ServerBootstrap 的创建和初始化
- 1.1 创建
- 1.2 初始化group
- 1.3 初始化channel
- 1.3 初始化option和attr
- 1.4 初始化handler 和 childHandler
- 总结
前言
接上一篇:手撕netty源码(一)- NioEventLoopGroup
本篇讲解 ServerBootstrap 的创建以及初始化:group、channel、option、attr、handler、childHandler
一、ServerBootstrap 的创建和初始化
public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>public class Bootstrap extends AbstractBootstrap<Bootstrap, Channel>
看的出来,AbstractBootstrap 是个比较重要的类,他里面其实包含了netty客户端和服务端的逻辑,所以有些属性和方法要注意一下
1.1 创建
创建很简单,只是new了一个对象而已
ServerBootstrap b = new ServerBootstrap();// io/netty/bootstrap/ServerBootstrap.java
public ServerBootstrap() {
}
1.2 初始化group
可以看到,这个操作其实只是初始化了 ServerBootstrap 的两个属性:group 和 childGroup
b.group(bossGroup, workerGroup)// io/netty/bootstrap/ServerBootstrap.java
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {super.group(parentGroup);if (this.childGroup != null) {throw new IllegalStateException("childGroup set already");}this.childGroup = ObjectUtil.checkNotNull(childGroup, "childGroup");return this;
}// 下面是super.group(parentGroup)
// io/netty/bootstrap/AbstractBootstrap.java
public B group(EventLoopGroup group) {ObjectUtil.checkNotNull(group, "group");if (this.group != null) {throw new IllegalStateException("group set already");}this.group = group;return self();
}
1.3 初始化channel
这一步其实是初始化 channelFactory ,可以看到,实际的channelFactory 实现是 ReflectiveChannelFactory,即通过反射来创建 channel,不过这里并没有开始创建 channel ,只是给 channelFactory 属性赋了值
b.channel(NioServerSocketChannel.class);//io/netty/bootstrap/AbstractBootstrap.java
public B channel(Class<? extends C> channelClass) {return channelFactory(new ReflectiveChannelFactory<C>(ObjectUtil.checkNotNull(channelClass, "channelClass")));
}//io/netty/bootstrap/AbstractBootstrap.java
public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory) {return channelFactory((ChannelFactory<C>) channelFactory);
}//io/netty/bootstrap/AbstractBootstrap.java
public B channelFactory(ChannelFactory<? extends C> channelFactory) {ObjectUtil.checkNotNull(channelFactory, "channelFactory");if (this.channelFactory != null) {throw new IllegalStateException("channelFactory set already");}this.channelFactory = channelFactory;return self();
}
1.3 初始化option和attr
AbstractBootstrap 定义了两个ConcurrentHashMap
- ChannelOption 主要是用于配置netty中一些相关的参数,这些参数的key已经在ChannelOption中以静态变量的方式设置好了,可以直接拿来使用,并且配置相关的value,如果ChannelOption设置了一个不存在的key,就会以日志的形式提示错误信息,但是不会抛出异常。
- AttributeKey 主要用于维护业务数据,业务数据随着业务流转
private final Map<ChannelOption<?>, Object> options = new ConcurrentHashMap();
private final Map<AttributeKey<?>, Object> attrs = new ConcurrentHashMap();public <T> B option(ChannelOption<T> option, T value) {ObjectUtil.checkNotNull(option, "option");if (value == null) {this.options.remove(option);} else {this.options.put(option, value);}return this.self();
}public <T> B attr(AttributeKey<T> key, T value) {ObjectUtil.checkNotNull(key, "key");if (value == null) {this.attrs.remove(key);} else {this.attrs.put(key, value);}return this.self();
}
稍微往里面看一看,会发现ChannelOption和AttributeKey都继承了AbstractConstant,且内部都使用ConstantPool维护了数据 。
这里注意一下:ChannelOption和AttributeKey都提供了方法valueOf和newInstance,二者的区别是 valueOf 同样的参数 多次调用返回的是同一个对象,而newInstance 同样的参数 多次调用返回的是不同的对象
1.4 初始化handler 和 childHandler
handler 被定义在AbstractBootstrap,childHandler 被定义在ServerBootstrap。所以 handler 服务端和客户端都会被用到,而childHandler 只有服务端可以用到
// io/netty/bootstrap/AbstractBootstrap.java
public B handler(ChannelHandler handler) {this.handler = ObjectUtil.checkNotNull(handler, "handler");return self();
}// io/netty/bootstrap/ServerBootstrap.java
public ServerBootstrap childHandler(ChannelHandler childHandler) {this.childHandler = ObjectUtil.checkNotNull(childHandler, "childHandler");return this;
}
总结
本文先简单介绍一下 ServerBootstrap 的创建和属性初始化赋值,并没有实质的操作,下一篇会讲解 bind 方法,这个方法里有很多内容