AbstractBootstrap是一个帮助类,通过方法链(method chaining)的方式,提供了一个简单易用的方式来配置Bootstrap,然后启动一个Channel。在理解Netty源码中的AbstractBootstrap, ServerBootstrap和Bootstrap之前,应该先了解一下什么是method chaining。
Wiki上面对于method chaining的定义如下:
Method chaining, is a common technique for invoking multiple method calls in object-oriented programming languages. Each method returns an object (possibly the current object itself), allowing the calls to be chained together in a single statement.
在面向对象的编程语言中,method chaining是一种用于调用多个方法的常用技术。每个方法都会返回一个对象(可能是当前对象本身),这样做的好处就是,通过一条语句,就可以讲所有的方法调用链接在一起。
定义有一些抽象,那么可以通过实际的例子来进行理解和消化。
假设有一个StringBuffer的类,类中有一个append()方法
public class StringBuffer {
public void append(String str) {
// useful code
}
}
这个类有缺点就是说,在向StringBuffer对象追加新的字符串的时候,需要在多条语句中,不断的调用append()方法。
StringBuffer sb = new StringBuffer();
sb.append("Hello ");
sb.append(name);
sb.append("! Welcome!");
而method chaining的实现,就可以避免这个缺陷。
public class StringBuffer {
public StringBuffer append(String str) {
// useful code
return this;
}
}
现在我们就可以再一条语句中实现第一个例子的功能了。
StringBuffer sb = new StringBuffer();
sb.append("Hello ").append(name).append("! Welcome!");
AbstractBootstrap抽象类 (部分代码)
package io.netty.bootstrap;
public abstract class AbstractBootstrap<B extends AbstractBootstrap<?>> {
private EventLoopGroup group;
private ChannelFactory factory;
private SocketAddress localAddress;
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
private ChannelHandler handler;
@SuppressWarnings("unchecked")
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 (B) this;
}
public B channel(Class<? extends Channel> channelClass) {
if (channelClass == null) {
throw new NullPointerException("channelClass");
}
return channelFactory(new BootstrapChannelFactory(channelClass));
}
@SuppressWarnings("unchecked")
public B channelFactory(ChannelFactory factory) {
if (factory == null) {
throw new NullPointerException("factory");
}
if (this.factory != null) {
throw new IllegalStateException("factory set already");
}
this.factory = factory;
return (B) this;
}
@SuppressWarnings("unchecked")
public B localAddress(SocketAddress localAddress) {
this.localAddress = localAddress;
return (B) this;
}
@SuppressWarnings("unchecked")
public <T> B option(ChannelOption<T> option, T value) {
if (option == null) {
throw new NullPointerException("option");
}
if (value == null) {
options.remove(option);
} else {
options.put(option, value);
}
return (B) this;
}
public <T> B attr(AttributeKey<T> key, T value) {
if (key == null) {
throw new NullPointerException("key");
}
if (value == null) {
attrs.remove(key);
} else {
attrs.put(key, value);
}
return (B) this;
}
@SuppressWarnings("unchecked")
public B handler(ChannelHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
this.handler = handler;
return (B) this;
}
}
AbstractBootstrap声明了六个私有的成员变量,EventLoopGroup对象,ChannelFacotry对象,SockteAddress对象,Map<ChannelOption<?>,Object>对象,Map<Attribute<?>,Object>对象,ChannelHandler对象。并且有相对应的方法,来设置这些对象,如
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 (B) this;
}
通过传进来的group对象,然后将AbstractBootstrap中的group指向传进来的group。最终返回的还是AbstractBootstrap这个当前对象。
六个对象的作用
EventLoopGroup group | 用于处理将要被创建的所有event |
ChannelFactory factory | 建立一个工厂,用于以后的Channel创建 |
SocketAddress localAddress; | 用于绑定本地的网络地址 |
Map<ChannelOption<?>, Object> options | 指定所创建Channel的选项,如TCP_NODELAY,AIO_READ_TIMEOUT |
Map<AttributeKey<?>, Object> attrs | 指定所创建Channel的属性 |
ChannelHandler handler | 用于处理各类请求 |
AbstractBootstrap抽象类的接口
AbstractBootstrap抽象类UML图
ServerBootstrap和Bootstrap
在Netty 4.0中,ServerBootstrap用于为服务器启动ServerChannel,Bootstrap用于为客服端启动Channel。这两个类是AbstractBootstrap的具体实现。
备注:因为笔者开始写Netty源码分析的时候,Netty 4.0还是处于Alpha阶段,之后的API可能还会有改动,笔者将会及时更改。使用开源已经有好几年的时间了,一直没有时间和精力来具体研究某个开源项目的具体实现,这次是第一次写开源项目的源码分析,如果文中有错误的地方,欢迎读者可以留言指出。对于转载的读者,请注明文章的出处。
希望和广大的开发者/开源爱好者进行交流,欢迎大家的留言和讨论。
-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;