??????
哈喽!大家好,我是「奇点」,江湖人称 singularity。刚工作几年,想和大家一同进步??
一位上进心十足的【Java ToB端大厂领域博主】!???
喜欢java和python,平时比较懒,能用程序解决的坚决不手动解决???
✨ 如果有对【java】感兴趣的【小可爱】,欢迎关注我❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️
————————————————
如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。
目录
6.3ChannelInboundHandlerAdapter
6.4ChannelOutboundHandlerAdapter
1.channelinboundhandler
2.channelHandlerContext
3.channelPipeline(事件如何流动)
入站事件由入站处理程序按照自底向上的方向处理,如图左侧所示。入站处理程序通常处理由关系图底部的I/O线程生成的入站数据。入站数据通常通过实际的输入操作(如SocketChannel.read(ByteBuffer))从远程对等端读取。如果入站事件超出了顶级入站处理程序,那么它将被无声地丢弃,或者需要注意时将被记录下来。
出站事件由出站处理程序按自顶向下的方向处理,如图右侧所示。出站处理程序通常生成或转换出站流量,比如写请求。如果出站事件超出底部出站处理程序,则由与通道关联的I/O线程处理。I/O线程通常执行实际的输出操作,如SocketChannel.write(ByteBuffer)。
在上面的示例中,名称以入站开头的类意味着它是一个入站处理程序。名称以出站开头的类意味着它是一个出站处理程序。
在给定的示例配置中,当事件进入到入站时,处理程序计算顺序为1、2、3、4、5。当一个事件出站时,顺序是5、4、3、2、1。基于这一原则,ChannelPipeline跳过了对某些处理程序的评估,以缩短堆栈深度
3和4没有实现ChannelInboundHandler,因此入站事件的实际评估顺序将是:1、2和5。
1和2没有实现ChannelOutboundHandler,因此出站事件的实际计算顺序将是:5、4和3。
如果5同时实现了ChannelInboundHandler和ChannelOutboundHandler,则入站事件和出站事件的计算顺序可以分别为125和543。
用户应该在管道中有一个或多个通道处理程序来接收I/O事件(例如读取)和请求I/O操作(例如写入和关闭)。例如,一个典型的服务器在每个通道的管道中都有以下处理程序,但是您的里程可能会根据协议和业务逻辑的复杂性和特征而有所不同:
协议解码器——将二进制数据(例如ByteBuf)转换成Java对象。
协议编码器——将Java对象转换成二进制数据。
业务逻辑处理程序——执行实际的业务逻辑(例如数据库访问)。
//告诉管道运行MyBusinessLogicHandler的事件处理程序方法
//在与I/O线程不同的线程中,这样I/O线程就不会被阻塞
//这是一项费时的工作。
//如果您的业务逻辑是完全异步的,或者完成得非常快,那么您就不需要这样做
//需要指定一个组。
可以随时添加或删除ChannelHandler,因为ChannelPipeline是线程安全的。例如,您可以在即将交换敏感信息时插入加密处理程序,并在交换之后删除它。
4.channelpipeline方法
3.接着上 channelHandlerContext
可以通过调用pipeline()获得处理程序所属的ChannelPipeline。一个重要的应用程序可以在运行时动态地插入、删除或替换管道中的处理程序。
可以保留ChannelHandlerContext供以后使用,例如在处理程序方法之外触发事件,甚至从不同的线程触发事件。
处理存储信息
attr(AttributeKey)允许存储和访问与处理程序及其上下文相关的有状态信息。请参考ChannelHandler了解管理有状态信息的各种推荐方法。
请注意,ChannelHandler实例可以添加到多个ChannelPipeline中。这意味着单个ChannelHandler实例可以有多个ChannelHandlerContext,因此,如果将单个实例多次添加到一个或多个channelpipeline中,则可以使用不同的ChannelHandlerContexts调用该实例。
例如,下面的处理程序将拥有与添加到管道多少次相同数量的独立attributekey,而不管它是多次添加到同一管道中,还是多次添加到不同管道中:
此处理程序将接收开始递增的整数序列
/ /从1。
//将不同的上下文对象赋给“f1”、“f2”、“f3”和“f4”,即使
//它们引用相同的处理程序实例。因为FactorialHandler
//将其状态存储在上下文对象中(使用AttributeKey),阶乘为
//两个管道(p1和p2)激活后,正确计算4次。
请参考ChannelHandler和ChannelPipeline,以了解关于入站和出站操作的更多信息,它们有哪些基本区别,它们在管道中如何流动,以及如何在应用程序中处理操作
5.channelHandlerContext方法
6.ChannelHandler
处理I/O事件或拦截I/O操作,并将其转发到其ChannelPipeline中的下一个处理程序。
使用ChannelHandler一般要实现下面的子类其中一种
ChannelHandler提供了一个ChannelHandlerContext对象。ChannelHandler应该通过上下文对象与它所属的ChannelPipeline交互。使用上下文对象,ChannelHandler可以向上或向下传递事件,动态修改管道,或者存储特定于处理程序的信息(使用AttributeKeys)。
ChannelHandler通常需要存储一些有状态的信息,最简单和推荐的方法是使用成员变量:
在上面使用AttributeKey的示例中,您可能注意到了@Sharable注释。
如果使用@Sharable注释注释ChannelHandler,这意味着您可以只创建一个处理程序实例一次,并多次将其添加到一个或多个channelpipeline中,而不需要使用竞态条件。
如果未指定此注释,则每次将其添加到管道时都必须创建一个新的处理程序实例,因为它具有成员变量等非共享状态。
与JCIP注释一样,这个注释是为文档目的提供的。
6.1ChannelInboundHandler
ChannelHandler为状态更改添加回调。这允许用户轻松地挂入状态更改。
6.2 ChannelOutboundHandler
6.3ChannelInboundHandlerAdapter
ChannelInboundHandler实现的抽象基类,它提供了所有方法的实现。
这个实现只是将操作转发到ChannelPipeline中的下一个ChannelHandler。子类可以覆盖方法实现来改变这一点。
注意,在channelRead(ChannelHandlerContext, Object)方法自动返回后,不会释放消息。如果您正在寻找自动释放接收到的消息的ChannelInboundHandler实现,请参见SimpleChannelInboundHandler。
6.4ChannelOutboundHandlerAdapter
好了,我们已经把netty的核心组件都学习完毕了,相信大家对netty有了更深入的了解。
如果觉得本文对你有帮助,欢迎点赞,欢迎关注我,如果有补充欢迎评论交流,我将努力创作更多更好的文章。