文章目录
- 前言
- 一、ServerBootstrap 的创建和初始化
- 1.1 创建
- 1.2 初始化group
- 1.3 初始化channel
- 1.3 初始化option和attr
- 1.4 初始化handler 和 childHandler
- 总结
前言
processOn文档跳转
接上一篇:手撕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 方法,这个方法里有很多内容