[#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;
|
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.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
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
|
* {@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}.
|
* 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 ChannelFactory factory;
|
||||||
private SocketAddress localAddress;
|
private SocketAddress localAddress;
|
||||||
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
|
private final Map<ChannelOption<?>, Object> options = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||||
|
private final Map<AttributeKey<?>, Object> attrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||||
private ChannelHandler handler;
|
private ChannelHandler handler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,6 +139,23 @@ public abstract class AbstractBootstrap<B extends AbstractBootstrap<?>> {
|
|||||||
return (B) this;
|
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
|
* Shutdown the {@link AbstractBootstrap} and the {@link EventLoopGroup} which is
|
||||||
* used by it. Only call this if you don't share the {@link EventLoopGroup}
|
* 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;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final Map<AttributeKey<?>, Object> attrs() {
|
||||||
|
return attrs;
|
||||||
|
}
|
||||||
|
|
||||||
private final class BootstrapChannelFactory implements ChannelFactory {
|
private final class BootstrapChannelFactory implements ChannelFactory {
|
||||||
private final Class<? extends Channel> clazz;
|
private final Class<? extends Channel> clazz;
|
||||||
|
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
package io.netty.bootstrap;
|
package io.netty.bootstrap;
|
||||||
|
|
||||||
import io.netty.channel.Channel;
|
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.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelFutureListener;
|
||||||
import io.netty.channel.ChannelOption;
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
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();
|
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.
|
* Create a new {@link Bootstrap} which has the identical configuration with this {@link Bootstrap}.
|
||||||
* Only the given parameters are replaced, the rest is configured exactly the same way as the template.
|
* 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();
|
validate();
|
||||||
Bootstrap cb = new Bootstrap().handler(handler).channelFactory(factory()).group(group())
|
Bootstrap b = new Bootstrap()
|
||||||
.localAddress(localAddress).remoteAddress(remoteAddress);
|
.group(group()).channelFactory(factory()).handler(handler())
|
||||||
cb.options().putAll(options());
|
.localAddress(localAddress()).remoteAddress(remoteAddress);
|
||||||
return cb;
|
b.options().putAll(options());
|
||||||
}
|
b.attrs().putAll(attrs());
|
||||||
|
return b;
|
||||||
/**
|
|
||||||
* 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());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ import io.netty.channel.ServerChannel;
|
|||||||
import io.netty.channel.socket.SocketChannel;
|
import io.netty.channel.socket.SocketChannel;
|
||||||
import io.netty.logging.InternalLogger;
|
import io.netty.logging.InternalLogger;
|
||||||
import io.netty.logging.InternalLoggerFactory;
|
import io.netty.logging.InternalLoggerFactory;
|
||||||
|
import io.netty.util.AttributeKey;
|
||||||
import io.netty.util.NetworkConstants;
|
import io.netty.util.NetworkConstants;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
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<ChannelOption<?>, Object> childOptions = new LinkedHashMap<ChannelOption<?>, Object>();
|
||||||
|
private final Map<AttributeKey<?>, Object> childAttrs = new LinkedHashMap<AttributeKey<?>, Object>();
|
||||||
private EventLoopGroup childGroup;
|
private EventLoopGroup childGroup;
|
||||||
private ChannelHandler childHandler;
|
private ChannelHandler childHandler;
|
||||||
|
|
||||||
@ -116,6 +118,18 @@ public class ServerBootstrap extends AbstractBootstrap<ServerBootstrap> {
|
|||||||
return this;
|
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.
|
* 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;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Entry<AttributeKey<?>, Object> e: attrs().entrySet()) {
|
||||||
|
channel.attr((AttributeKey<Object>) e.getKey()).set(e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
ChannelPipeline p = future.channel().pipeline();
|
ChannelPipeline p = future.channel().pipeline();
|
||||||
if (handler() != null) {
|
if (handler() != null) {
|
||||||
p.addLast(handler());
|
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 {
|
try {
|
||||||
childGroup.register(child);
|
childGroup.register(child);
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
|
Loading…
Reference in New Issue
Block a user