AbstractBootstrap是一個(gè)幫助類,通過方法鏈(method chaining)的方式,提供了一個(gè)簡(jiǎn)單易用的方式來配置Bootstrap,然后啟動(dòng)一個(gè)Channel。在理解Netty源碼中的AbstractBootstrap, ServerBootstrap和Bootstrap之前,應(yīng)該先了解一下什么是method chaining。
Wiki上面對(duì)于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.
在面向?qū)ο蟮木幊陶Z言中,method chaining是一種用于調(diào)用多個(gè)方法的常用技術(shù)。每個(gè)方法都會(huì)返回一個(gè)對(duì)象(可能是當(dāng)前對(duì)象本身),這樣做的好處就是,通過一條語句,就可以講所有的方法調(diào)用鏈接在一起。
定義有一些抽象,那么可以通過實(shí)際的例子來進(jìn)行理解和消化。
假設(shè)有一個(gè)StringBuffer的類,類中有一個(gè)append()方法
public class StringBuffer {
public void append(String str) {
//
useful code 
}
}
這個(gè)類有缺點(diǎn)就是說,在向StringBuffer對(duì)象追加新的字符串的時(shí)候,需要在多條語句中,不斷的調(diào)用append()方法。
StringBuffer sb = new StringBuffer();
sb.append("Hello ");
sb.append(name);
sb.append("! Welcome!");
而method chaining的實(shí)現(xiàn),就可以避免這個(gè)缺陷。
public class StringBuffer {
public StringBuffer append(String str) {
//
useful code 
return this;
}
}
現(xiàn)在我們就可以再一條語句中實(shí)現(xiàn)第一個(gè)例子的功能了。
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聲明了六個(gè)私有的成員變量,EventLoopGroup對(duì)象,ChannelFacotry對(duì)象,SockteAddress對(duì)象,Map<ChannelOption<?>,Object>對(duì)象,Map<Attribute<?>,Object>對(duì)象,ChannelHandler對(duì)象。并且有相對(duì)應(yīng)的方法,來設(shè)置這些對(duì)象,如
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;
}
通過傳進(jìn)來的group對(duì)象,然后將AbstractBootstrap中的group指向傳進(jìn)來的group。最終返回的還是AbstractBootstrap這個(gè)當(dāng)前對(duì)象。
六個(gè)對(duì)象的作用
EventLoopGroup group | 用于處理將要被創(chuàng)建的所有event |
ChannelFactory factory | 建立一個(gè)工廠,用于以后的Channel創(chuàng)建 |
SocketAddress localAddress; | 用于綁定本地的網(wǎng)絡(luò)地址 |
Map<ChannelOption<?>, Object> options | 指定所創(chuàng)建Channel的選項(xiàng),如TCP_NODELAY,AIO_READ_TIMEOUT |
Map<AttributeKey<?>, Object> attrs | 指定所創(chuàng)建Channel的屬性 |
ChannelHandler handler | 用于處理各類請(qǐng)求 |
AbstractBootstrap抽象類的接口

AbstractBootstrap抽象類UML圖
ServerBootstrap和Bootstrap
在Netty 4.0中,ServerBootstrap用于為服務(wù)器啟動(dòng)ServerChannel,Bootstrap用于為客服端啟動(dòng)Channel。這兩個(gè)類是AbstractBootstrap的具體實(shí)現(xiàn)。
備注:因?yàn)楣P者開始寫Netty源碼分析的時(shí)候,Netty 4.0還是處于Alpha階段,之后的API可能還會(huì)有改動(dòng),筆者將會(huì)及時(shí)更改。使用開源已經(jīng)有好幾年的時(shí)間了,一直沒有時(shí)間和精力來具體研究某個(gè)開源項(xiàng)目的具體實(shí)現(xiàn),這次是第一次寫開源項(xiàng)目的源碼分析,如果文中有錯(cuò)誤的地方,歡迎讀者可以留言指出。對(duì)于轉(zhuǎn)載的讀者,請(qǐng)注明文章的出處。
希望和廣大的開發(fā)者/開源愛好者進(jìn)行交流,歡迎大家的留言和討論。
-----------------------------------------------------
Silence, the way to avoid many problems;
Smile, the way to solve many problems;