前言:已经初始化了NioEventLoopGroup 的boosGroup 和 workerGroup ,那么ServerBootstrap的作用是干嘛的呢 ,本文在Spring架构篇–2.7.1 远程通信基础–Netty原理–NioEventLoopGroup 之后继续进行探究
1 首先回顾下 nettt 的使用demo:
public class DiscardServer {
private int port;
public DiscardServer(int port) {
this.port = port;
}
public static void main(String[] args) {
new DiscardServer(8080).run();
}
private void run() {
NioEventLoopGroup boss = new NioEventLoopGroup();
NioEventLoopGroup worker = new NioEventLoopGroup();
try {
ServerBootstrap server = new ServerBootstrap();
server.group(boss,worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new DiscardServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG,128)
.childOption(ChannelOption.SO_KEEPALIVE,true);
ChannelFuture f = server.bind(this.port).sync();
System.out.println("8080服务已启动");
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
可以看到ServerBootstrap 的对象做了一系列的配置后最终 通过 bind(this.port).sync() 进行启动;
2 ServerBootstrap 类:
2.1 new ServerBootstrap() 工作内容:
public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap, ServerChannel>
private static final InternalLogger logger = InternalLoggerFactory.getInstance(ServerBootstrap.class);
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap();
private final Map<AttributeKey<?>, Object> childAttrs = new ConcurrentHashMap();
// ServerBootstrap 对象赋值给 config
private final ServerBootstrapConfig config = new ServerBootstrapConfig(this);
private volatile EventLoopGroup childGroup;
private volatile ChannelHandler childHandler;
public ServerBootstrap() {
}
AbstractBootstrap 类
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable {
static final Map.Entry<ChannelOption<?>, Object>[] EMPTY_OPTION_ARRAY = new Map.Entry[0];
static final Map.Entry<AttributeKey<?>, Object>[] EMPTY_ATTRIBUTE_ARRAY = new Map.Entry[0];
volatile EventLoopGroup group;
private volatile ChannelFactory<? extends C> channelFactory;
private volatile SocketAddress localAddress;
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap();
private final Map<AttributeKey<?>, Object> attrs = new ConcurrentHashMap();
private volatile ChannelHandler handler;
AbstractBootstrap() {
}
}
- 可以看到ServerBootstrap 继承了AbstractBootstrap类,当new ServerBootstrap() 时,对ServerBootstrap和AbstractBootstrap类都通过无参的构造方法,完成了这两个类的对象实例化;
- 可以看到ServerBootstrap和AbstractBootstrap这两个类的属性非常相似,实际上 ServerBootstrap 用来放NioEventLoopGroup 工作线程的数据;AbstractBootstrap 用来放 boss 线程的数据;
- 可以看到这里只是进行了初始化,里面的属性都还没有进行赋值,两个对象的属性值都是默认值;
2.2 ServerBootstrap ,AbstractBootstrap 的属性赋值:
2.2.1 server.group(boss,worker):完成对父类和子类 NioEventLoopGroup对象进行赋值
ServerBootstrap 类的 group 方法:
public ServerBootstrap group(EventLoopGroup parentGroup, EventLoopGroup childGroup) {
// 父类AbstractBootstrap 的EventLoopGroup 赋值
super.group(parentGroup);
if (this.childGroup != null) {
throw new IllegalStateException("childGroup set already");
} else {
// 子类的EventLoopGroup volatile EventLoopGroup group 赋值;
this.childGroup = (EventLoopGroup)ObjectUtil.checkNotNull(childGroup, "childGroup");
return this;
}
}
super.group(parentGroup); 父类对象的赋值:
AbstractBootstrap 的group 方法:
static final Map.Entry<ChannelOption<?>, Object>[] EMPTY_OPTION_ARRAY = new Map.Entry[0];
static final Map.Entry<AttributeKey<?>, Object>[] EMPTY_ATTRIBUTE_ARRAY = new Map.Entry[0];
volatile EventLoopGroup group;
private volatile ChannelFactory<? extends C> channelFactory;
private volatile SocketAddress localAddress;
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap();
private final Map<AttributeKey<?>, Object> attrs = new ConcurrentHashMap();
private volatile ChannelHandler handler;
AbstractBootstrap() {
}
// 父类的EventLoopGroup 赋值
AbstractBootstrap(AbstractBootstrap<B, C> bootstrap) {
this.group = bootstrap.group;
this.channelFactory = bootstrap.channelFactory;
this.handler = bootstrap.handler;
this.localAddress = bootstrap.localAddress;
synchronized(bootstrap.options) {
this.options.putAll(bootstrap.options);
}
this.attrs.putAll(bootstrap.attrs);
}
// 父类group AbstractBootstrap 类 对象的赋值 volatile EventLoopGroup group;
public B group(EventLoopGroup group) {
ObjectUtil.checkNotNull(group, "group");
if (this.group != null) {
throw new IllegalStateException("group set already");
} else {
this.group = group;
return this.self();
}
}
2.2.2 channel(NioServerSocketChannel.class):
AbstractBootstrap 类 private volatile ChannelFactory<? extends C> channelFactory; 对象赋值
调用 AbstractBootstrap 类中 channel(NioServerSocketChannel.class) 方法:
public B channel(Class<? extends C> channelClass) {
// 先使用ReflectiveChannelFactory 反射工厂类,对传入的channel 进行包装
// 调用channelFactory 对父类AbstractBootstrap 对象channel 工厂进行初始化
return this.channelFactory((io.netty.channel.ChannelFactory)(new ReflectiveChannelFactory((Class)ObjectUtil.checkNotNull(channelClass, "channelClass"))));
}
// 工厂方法调用
public B channelFactory(io.netty.channel.ChannelFactory<? extends C> channelFactory) {
return this.channelFactory((ChannelFactory)channelFactory);
}
// AbstractBootstrap 对象属性的初始化
@Deprecated
public B channelFactory(ChannelFactory<? extends C> channelFactory) {
ObjectUtil.checkNotNull(channelFactory, "channelFactory");
if (this.channelFactory != null) {
throw new IllegalStateException("channelFactory set already");
} else {
this.channelFactory = channelFactory;
return this.self();
}
}
// channel类反射工厂的创建
public class ReflectiveChannelFactory<T extends Channel> implements ChannelFactory<T> {
private final Constructor<? extends T> constructor;
public ReflectiveChannelFactory(Class<? extends T> clazz) {
ObjectUtil.checkNotNull(clazz, "clazz");
try {
// 赋值 NioServerSocketChannel 类的构造器,使得在需要实例化channel 对象的时候
// 可以通过改channel 的无参构造方法完成对象实例化
this.constructor = clazz.getConstructor();
} catch (NoSuchMethodException var3) {
throw new IllegalArgumentException("Class " + StringUtil.simpleClassName(clazz) + " does not have a public non-arg constructor", var3);
}
}
// 对当前的channel 通过反射调用channel 对象的无参构造方法
public T newChannel() {
try {
return (Channel)this.constructor.newInstance();
} catch (Throwable var2) {
throw new ChannelException("Unable to create Channel from class " + this.constructor.getDeclaringClass(), var2);
}
}
public String toString() {
return StringUtil.simpleClassName(ReflectiveChannelFactory.class) + '(' + StringUtil.simpleClassName(this.constructor.getDeclaringClass()) + ".class)";
}
}
- 通过channle 方法可以看到,完成了对父类AbstractBootstrap 对象 channel 工厂的属性初始化;
- 在真正需要NioServerSocketChannel 对象的时候,可以通过ReflectiveChannelFactory的 newChannel() 方法完成对 NioServerSocketChannel 无参的构造方法调用,从而实例化一个NioServerSocketChannel的对象出来;
2.2.3 childHandler(new ChannelInitializer() { }):
调用ServerBootstrap 类中 childHandler(ChannelHandler childHandler) 方法:
public ServerBootstrap childHandler(ChannelHandler childHandler) {
this.childHandler = (ChannelHandler)ObjectUtil.checkNotNull(childHandler, "childHandler");
return this;
}
对ServerBootstrap 事件处理属性private volatile ChannelHandler childHandler; 赋值;
2.2.4 option(ChannelOption.SO_BACKLOG,128):
AbstractBootstrap 的option 方法,对父类AbstractBootstrap 对象options 顺序赋值:
// private final Map<ChannelOption<?>, Object> options = new LinkedHashMap(); 属性赋值
public <T> B option(ChannelOption<T> option, T value) {
ObjectUtil.checkNotNull(option, "option");
synchronized(this.options) {
if (value == null) {
this.options.remove(option);
} else {
this.options.put(option, value);
}
}
return this.self();
}
2.2.5 childOption(ChannelOption.SO_KEEPALIVE,true):
ServerBootstrap 类中的childOption 方法:文章来源:https://www.toymoban.com/news/detail-475299.html
// private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap(); 赋值
public <T> ServerBootstrap childOption(ChannelOption<T> childOption, T value) {
ObjectUtil.checkNotNull(childOption, "childOption");
synchronized(this.childOptions) {
if (value == null) {
this.childOptions.remove(childOption);
} else {
this.childOptions.put(childOption, value);
}
return this;
}
}
- 可以看到上面的这些步骤先是对ServerBootstrap 和AbstractBootstrap 对象实例化 然后为其属性进行赋值操作;
- 将NioEventLoopGroup worker = new NioEventLoopGroup(); 的worker 对象对其ServerBootstrap 的EventLoopGroup childGroup 赋值;然后将 NioEventLoopGroup boss = new NioEventLoopGroup(); 对象对其AbstractBootstrap 的 volatile EventLoopGroup group 属性赋值;
- 对AbstractBootstrap 的channel 工厂类属性 private volatile ChannelFactory<? extends C> channelFactory; 赋值为NioServerSocketChannel 对象工厂;
- 对AbstractBootstrap 的options 属性赋值key:ChannelOption.SO_BACKLOG, value :128;
- 对ServerBootstrap 的childOptions 属性赋值key:ChannelOption.SO_KEEPALIVE, value: true;
以上步骤都是初始化和赋值操作,没有socket 端口的绑定,以及时间监听的处理,那么这些处理就只剩在bind(this.port).sync() 进行处理,由于bind 方法嵌套较深,所有放在下一篇继续探究;文章来源地址https://www.toymoban.com/news/detail-475299.html
到了这里,关于Spring架构篇--2.7.2 远程通信基础--Netty原理--ServerBootstrap的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!