這裏小結一下netty的一些知識點。安全
當某個ChannelInboundHandler的實現重寫channelRead()方法時,它將負責顯式地釋放與池化的ByteBuf實例相關的內存。Netty爲此提供了一個實用方法ReferenceCountUtil.release() 可是以這種方式管理資源可能很繁瑣。併發
一個更加簡單的方式是使用SimpleChannelInboundHandler。 因爲SimpleChannelInboundHandler會自動釋放資源,因此你不該該存儲指向任何消息的引用供未來使用,由於這些引用都將會失效。oop
標註一個channel handler能夠被多個channel安全地共享。 線程
ChannelHandlerAdapter還提供了實用方法isSharable()。若是其對應的實現被標註爲Sharable,那麼這個方法將返回true,表示它能夠被添加到多個ChannelPipeline中。 netty
由於一個ChannelHandler能夠從屬於多個ChannelPipeline,因此它也能夠綁定到多個ChannelHandlerContext實例。用於這種用法的ChannelHandler必需要使用@Sharable註解標註;不然,試圖將它添加到多個ChannelPipeline時將會觸發異常。顯而易見,爲了安全地被用於多個併發的Channel(即鏈接),這樣的ChannelHandler必須是線程安全的。code
ChannelPipeline是一個攔截流經Channel的入站和出站事件的ChannelHandler實例鏈。 生命週期
每個新建立的Channel都將會被分配一個新的ChannelPipeline。這項關聯是永久性的;Channel既不能附加另一個ChannelPipeline,也不能分離其當前的。在Netty組件的生命週期中,這是一項固定的操做,不須要開發人員的任何干預。 根據事件的起源,事件將會被ChannelInboundHandler或者ChannelOutbboundHandler處理。隨後,經過調用ChannelHandlerContext實現,它將被轉發給同一超類型的下一個ChannelHandler。事件
對於進站事件來講,先添加的先執行。 對於出站事件來講,後添加的先執行。ip
將經過ChannelHandlerContext獲取到Channel的引用。調用Channel上的write()方法將會致使寫入事件從尾端到頭部地流經ChannelPipeline:內存
ctx.getPipeline().write()
要想調用從某個特定的ChannelHandler開始的處理過程,必須獲取到在(ChannelPipeline)該ChannelHandler以前的ChannelHandler所關聯的ChannnelHandlerContext。這個ChannelHandlerContext將調用和它所關聯的ChannelHandler以後的ChannelHandler:
ctx.write()
消息將從下一個ChannelHandler開始流經ChannelPipeline,繞過了全部前面的ChannelHandler。
netty提供了一種將多個ChannelHandler添加到一個ChannelPipeline中的簡便方法。你只須要簡單地向Bootstrap或ServerBootstrap的實例提供你的ChannelInitializer實現便可,而且一旦Channel被註冊到了它的EventLoop以後,就會調用你的initChannel()版本。在該方法返回以後,ChannelInitializer的實例將會從ChannelPipeline中移除它本身。
在大部分的場景下,若是你不須要使用只存在於SocketChannel上的方法,使用ChannelInitializer就能夠了,不然你可使用ChannelInitializer,其中SocketChannel擴展了Channel。 若是你的應用程序使用了多個ChannelHandler,請定義你本身的ChannelInitializer實現來將它們安裝到ChannelPipeline中。