Sharable的应用案例
先直观感受一下该注解的影响:
|
|
如上代码,在第二个客户端连接的时候,会报如下错误:
io.netty.channel.ChannelPipelineException: shareable.Server$Handler is not a @Sharable handler, so can't be added or removed multiple times.
at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:600)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:202)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:381)
at io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:370)
at shareable.Server$1.initChannel(Server.java:27)
at shareable.Server$1.initChannel(Server.java:24)
at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:129)
at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:112)
at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:938)
at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609)
at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:46)
at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1463)
at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1115)
at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:650)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:514)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:164)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:469)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:500)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.lang.Thread.run(Thread.java:748)
如果在Handler上增加@Shareable
注解,就不会存在这个问题。
ChannelHandlerAdapter对其的支持
ChannelHandlerAdapter仅包含如下两个有价值的实现:
|
|
这两个方法在什么时候会用到呢?在pipeline的addLast方法中有如下代码:
|
|
isSharable的实现如下:
|
|
InternalThreadLocalMap.get().handlerSharableCache()
为一个空Map,其资源是在cache.put(clazz, sharable)
中放置进去的。搞SpringBoot多了,总感觉有些东西是在启动时通过反射之类的方法加载的,我还在找@Sharable的实现类,没想到用了这么简单的一个方案处理。
ChannelHandlerAdapter中其他实现
|
|
已经废除了,研究价值不是很大,@Skip
比较新颖,有点意思。