BootStrap是客户端启动器,只增加了一个字段
private volatile SocketAddress remoteAddress;
int()方法和serverBootStrap的init()的方法相比,非常简单。在配置处理链时没有增加最后一个尾部的接收处理器。
其余的和serverBootStrap的init()的方法差不多,都是初始化处理器链,初始化选项参数以及属性键值对。
void init(Channel channel) throws Exception {
ChannelPipeline p = channel.pipeline();
//初始化处理器链
p.addLast(new ChannelHandler[]{this.config.handler()});
Map<ChannelOption<?>, Object> options = this.options0();
synchronized(options) {//初始化选项参数
setChannelOptions(channel, options, logger);
}
Map<AttributeKey<?>, Object> attrs = this.attrs0();
synchronized(attrs) {//初始化属性键值对
Iterator var6 = attrs.entrySet().iterator();
while(var6.hasNext()) {
Entry<AttributeKey<?>, Object> e = (Entry)var6.next();
channel.attr((AttributeKey)e.getKey()).set(e.getValue());
}
}
}
BootStrap的最重要的方法应该就是connect()方法了,ServerBootStrap不是bind()方法是因为这个方法是在其父类的AbstractBootStrap里主要实现的(是因为在ServerBootStrap的parentGroup是在AbstractBootStrap里初始化完成的)
public ChannelFuture connect() {
this.validate();//验证数据是否有效
SocketAddress remoteAddress = this.remoteAddress;
if (remoteAddress == null) {
throw new IllegalStateException("remoteAddress not set");
} else {
return this.doResolveAndConnect(remoteAddress, this.config.localAddress());
}
}
private ChannelFuture doResolveAndConnect(final SocketAddress remoteAddress, final SocketAddress localAddress) {
ChannelFuture regFuture = this.initAndRegister();//和serverBootStrap一样,调用的是AbstractBootStrap,只不过里面的init调用的是自己的init方法
final Channel channel = regFuture.channel();
if (regFuture.isDone()) {
return !regFuture.isSuccess() ? regFuture : this.doResolveAndConnect0(channel, remoteAddress, localAddress, channel.newPromise());//三目运算表达式,成功了则调用doResolveAndConnect0
} else {//异步的,所以在未完成的情况下添加一个listener,注册回调函数
final PendingRegistrationPromise promise = new PendingRegistrationPromise(channel);
regFuture.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) throws Exception {
Throwable cause = future.cause();
if (cause != null) {
promise.setFailure(cause);
} else {
promise.registered();
Bootstrap.this.doResolveAndConnect0(channel, remoteAddress, localAddress, promise);
}
}
});
return promise;
}
}
private ChannelFuture doResolveAndConnect0(final Channel channel, SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) {
try {
EventLoop eventLoop = channel.eventLoop();
AddressResolver<SocketAddress> resolver = this.resolver.getResolver(eventLoop);
if (!resolver.isSupported(remoteAddress) || resolver.isResolved(remoteAddress)) {
doConnect(remoteAddress, localAddress, promise);
return promise;
}
Future<SocketAddress> resolveFuture = resolver.resolve(remoteAddress);
if (resolveFuture.isDone()) {
Throwable resolveFailureCause = resolveFuture.cause();
if (resolveFailureCause != null) {
channel.close();
promise.setFailure(resolveFailureCause);
} else {
doConnect((SocketAddress)resolveFuture.getNow(), localAddress, promise);
}
return promise;
}
resolveFuture.addListener(new FutureListener<SocketAddress>() {
public void operationComplete(Future<SocketAddress> future) throws Exception {
if (future.cause() != null) {
channel.close();
promise.setFailure(future.cause());
} else {
Bootstrap.doConnect((SocketAddress)future.getNow(), localAddress, promise);
}
}
});
} catch (Throwable var9) {
promise.tryFailure(var9);
}
return promise;
}
private static void doConnect(final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise connectPromise) {
final Channel channel = connectPromise.channel();
channel.eventLoop().execute(new Runnable() {
public void run() {
if (localAddress == null) {
channel.connect(remoteAddress, connectPromise);
} else {
channel.connect(remoteAddress, localAddress, connectPromise);
}
connectPromise.addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
});
}