[#275 & #686] Ability to pass a custom parameter to Bootstrap.connect() / Replace Bootstrap.newBootstrap() with duplicate()
- Add Bootstrap.attr() and ServerBootstrap.attr()/childAttr() so that a user can initialize the attribute map from the beginning. - Replace newBootstrap() with duplicate()
This commit is contained in:
parent
fb6ce4989a
commit
43dc0bd8a3
@ -16,19 +16,20 @@
|
||||
|
||||
package io.netty.bootstrap;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelException;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelException;
|
||||
|
||||
/**
|
||||
* {@link AbstractBootstrap} is a helper class that makes it easy to bootstrap a {@link Channel}. It support
|
||||
* method-chaining to provide an easy way to configure the {@link AbstractBootstrap}.
|
||||
@ -39,6 +40,7 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<?>> {
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -137,6 +139,23 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<?>> {
|
||||
return (B) this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow to specify an initial attribute of the newly created {@link Channel}. If the {@code value} is
|
||||
* {@code null}, the attribute of the specified {@code key} is removed.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shutdown the {@link AbstractBootstrap} and the {@link EventLoopGroup} which is
|
||||
* used by it. Only call this if you don't share the {@link EventLoopGroup}
|
||||
@ -224,6 +243,10 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<?>> {
|
||||
return options;
|
||||
}
|
||||
|
||||
protected final Map<AttributeKey<?>, Object> attrs() {
|
||||
return attrs;
|
||||
}
|
||||
|
||||
private final class BootstrapChannelFactory implements ChannelFactory {
|
||||
private final Class<? extends Channel> clazz;
|
||||
|
||||
|
@ -16,13 +16,13 @@
|
||||
package io.netty.bootstrap;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelFutureListener;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.AttributeKey;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
@ -149,6 +149,10 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap> {
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<AttributeKey<?>, Object> e: attrs().entrySet()) {
|
||||
channel.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||
}
|
||||
|
||||
group().register(channel).syncUninterruptibly();
|
||||
}
|
||||
|
||||
@ -161,22 +165,16 @@ public class Bootstrap extends AbstractBootstrap<Bootstrap> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Bootstrap} using this "full-setup" {@link Bootstrap} as template.
|
||||
* Only the given parameters are replaced, the rest is configured exactly the same way as the template.
|
||||
* Create a new {@link Bootstrap} which has the identical configuration with this {@link Bootstrap}.
|
||||
* This method is useful when you make multiple connections with similar settings.
|
||||
*/
|
||||
public Bootstrap newBootstrap(SocketAddress localAddress, SocketAddress remoteAddress, ChannelHandler handler) {
|
||||
public Bootstrap duplicate() {
|
||||
validate();
|
||||
Bootstrap cb = new Bootstrap().handler(handler).channelFactory(factory()).group(group())
|
||||
.localAddress(localAddress).remoteAddress(remoteAddress);
|
||||
cb.options().putAll(options());
|
||||
return cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Bootstrap} using this "full-setup" {@link Bootstrap} as template.
|
||||
* Only the given parameters are replaced, the rest is configured exactly the same way as the template.
|
||||
*/
|
||||
public Bootstrap newBootstrap(SocketAddress localAddress, SocketAddress remoteAddress) {
|
||||
return newBootstrap(localAddress, remoteAddress, handler());
|
||||
Bootstrap b = new Bootstrap()
|
||||
.group(group()).channelFactory(factory()).handler(handler())
|
||||
.localAddress(localAddress()).remoteAddress(remoteAddress);
|
||||
b.options().putAll(options());
|
||||
b.attrs().putAll(attrs());
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
@ -32,6 +32,7 @@ import io.netty.channel.ServerChannel;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.logging.InternalLogger;
|
||||
import io.netty.logging.InternalLoggerFactory;
|
||||
import io.netty.util.AttributeKey;
|
||||
import io.netty.util.NetworkConstants;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
@ -57,6 +58,7 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap> {
|
||||
};
|
||||
|
||||
private final Map<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||
private EventLoopGroup childGroup;
|
||||
private ChannelHandler childHandler;
|
||||
|
||||
@ -116,6 +118,18 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> ServerBootstrap childAttr(AttributeKey<T> childKey, T value) {
|
||||
if (childKey == null) {
|
||||
throw new NullPointerException("childKey");
|
||||
}
|
||||
if (value == null) {
|
||||
childAttrs.remove(childKey);
|
||||
} else {
|
||||
childAttrs.put(childKey, value);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link ChannelHandler} which is used to server the request for the {@link Channel}'s.
|
||||
*/
|
||||
@ -151,6 +165,10 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap> {
|
||||
return future;
|
||||
}
|
||||
|
||||
for (Entry<AttributeKey<?>, Object> e: attrs().entrySet()) {
|
||||
channel.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||
}
|
||||
|
||||
ChannelPipeline p = future.channel().pipeline();
|
||||
if (handler() != null) {
|
||||
p.addLast(handler());
|
||||
@ -227,6 +245,10 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap> {
|
||||
}
|
||||
}
|
||||
|
||||
for (Entry<AttributeKey<?>, Object> e: childAttrs.entrySet()) {
|
||||
child.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||
}
|
||||
|
||||
try {
|
||||
childGroup.register(child);
|
||||
} catch (Throwable t) {
|
||||
|
Loading…
Reference in New Issue
Block a user