@Sharable 注解用来说明ChannelHandler是否可以在多个channel直接共享使用。下面我们做一个实验。
1.Channel共享ChannelHandler对象。但是这个ChannelHandler没有添加@Sharable注解
public static void start() throws InterruptedException { final EchoServerHandler echoServerHandler = new EchoServerHandler(); EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(group) .channel(NioServerSocketChannel.class) .localAddress(8000) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(echoServerHandler); } }); ChannelFuture future = bootstrap.bind().sync(); future.channel().closeFuture().sync(); } finally { group.shutdownGracefully().sync(); } }当客户端第二次请求的时候回报如下错误
io.netty.channel.ChannelPipelineException: com.zhp.springbootstreamdemo.net.EchoServerHandler is not a @Sharable handler, so can't be added or removed multiple times.
我们看一下源代码
private static void checkMultiplicity(ChannelHandler handler) { if (handler instanceof ChannelHandlerAdapter) { ChannelHandlerAdapter h = (ChannelHandlerAdapter) handler; if (!h.isSharable() && h.added) { throw new ChannelPipelineException( h.getClass().getName() + " is not a @Sharable handler, so can't be added or removed multiple times."); } h.added = true; } }当我们向ChannelPipeline中添加ChannelHandler 的时候会调用这个方法进行检查。
如果我们不共享ChannelHandler如下:
@Override protected void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new EchoServerHandler()); }这种情况下加不加@ Sharable 效果都是一样的。每个Channel使用不通的ChannelHandler 对象。