请戳GitHub原文: github.com/wangzhiwubi…

更多文章关注:多线程/集合/分布式/Netty/NIO/RPC

  • Java高级特性增强-集合
  • Java高级特性增强-多线程
  • Java高级特性增强-Synchronized
  • Java高级特性增强-volatile
  • Java高级特性增强-并发集合框架
  • Java高级特性增强-分布式
  • Java高级特性增强-Zookeeper
  • Java高级特性增强-JVM
  • Java高级特性增强-NIO
  • RPC
  • zookeeper
  • JVM
  • NIO
  • 其他更多

Netty中的Handler简介

Handler在Netty中,占据着非常重要的地位。Handler与Servlet中的filter很像,通过Handler可以完成通讯报文的解码编码、拦截指定的报文、

统一对日志错误进行处理、统一对请求进行计数、控制Handler执行与否。一句话,没有它做不到的只有你想不到的

  Netty中的所有handler都实现自ChannelHandler接口。按照输入输出来分,分为ChannelInboundHandlerChannelOutboundHandler两大类

ChannelInboundHandler对从客户端发往服务器的报文进行处理,一般用来执行解码、读取客户端数据、进行业务处理等;ChannelOutboundHandler

对从服务器发往客户端的报文进行处理,一般用来进行编码、发送报文到客户端

  Netty中可以注册多个handler。ChannelInboundHandler按照注册的先后顺序执行;ChannelOutboundHandler按照注册的先后顺序逆序执行。

  • 全网唯一一个从0开始帮助Java开发者转做大数据领域的公众号~
  • 公众号大数据技术与架构或者搜索import_bigdata关注,大数据学习路线最新更新,已经有很多小伙伴加入了~

ChannelPipeline中的事件不会自动流动,而我们一般需求事件自动流动,Netty提供了两个Adapter:ChannelInboundHandlerAdapter和ChannelOutboundHandlerAdapter来满足这种需求。其中的实现类似如下:

    // inboud事件默认处理过程public void channelRegistered(ChannelHandlerContext ctx) throws Exception {ctx.fireChannelRegistered();    // 事件传播到下一个Handler}// outboud事件默认处理过程public void bind(ChannelHandlerContext ctx, SocketAddress localAddress,ChannelPromise promise) throws Exception {ctx.bind(localAddress, promise);  // 事件传播到下一个Handler}复制代码

在Adapter中,事件默认自动传播到下一个Handler,这样带来的另一个好处是:用户的Handler类可以继承Adapter且覆盖自己感兴趣的事件实现,其他事件使用默认实现,不用再实现ChannelIn/outboudHandler接口中所有方法,提高效率。 我们常常遇到这样的需求:在一个业务逻辑处理器中,需要写数据库、进行网络连接等耗时业务。Netty的原则是不阻塞I/O线程,所以需指定Handler执行的线程池,可使用如下代码:

 static final EventExecutorGroup group = new DefaultEventExecutorGroup(16);...ChannelPipeline pipeline = ch.pipeline();// 简单非阻塞业务,可以使用I/O线程执行pipeline.addLast("decoder", new MyProtocolDecoder());pipeline.addLast("encoder", new MyProtocolEncoder());// 复杂耗时业务,使用新的线程池pipeline.addLast(group, "handler", new MyBusinessLogicHandler());
复制代码

ChannelHandler中有一个Sharable注解,使用该注解后多个ChannelPipeline中的Handler对象实例只有一个,从而减少Handler对象实例的创建。代码示例如下:

    public class DataServerInitializer extends ChannelInitializer<Channel> {private static final DataServerHandler SHARED = new DataServerHandler();@Overridepublic void initChannel(Channel channel) {channel.pipeline().addLast("handler", SHARED);}}
复制代码

Sharable注解的使用是有限制的,多个ChannelPipeline只有一个实例,所以该Handler要求无状态。上述示例中,DataServerHandler的事件处理方法中,不能使用或改变本身的私有变量,因为ChannelHandler是非线程安全的,使用私有变量会造成线程竞争而产生错误结果。

ChannelHandlerContext

Context指上下文关系,ChannelHandler的Context指的是ChannleHandler之间的关系以及ChannelHandler与ChannelPipeline之间的关系。ChannelPipeline中的事件传播主要依赖于ChannelHandlerContext实现,由于ChannelHandlerContext中有ChannelHandler之间的关系,所以能得到ChannelHandler的后继节点,从而将事件传播到下一个ChannelHandler。

ChannelHandlerContext继承自AttributeMap,所以提供了attr()方法设置和删除一些状态属性值,用户可将业务逻辑中所需使用的状态属性值存入到Context中。此外,Channel也继承自AttributeMap,也有attr()方法,在Netty4.0中,这两个attr()方法并不等效,这会给用户程序员带来困惑并且增加内存开销,所以Netty4.1中将channel.attr()==ctx.attr()。在使用Netty4.0时,建议只使用channel.attr()防止引起不必要的困惑。

一个Channel对应一个ChannelPipeline,一个ChannelHandlerContext对应一个ChannelHandler,但一个ChannelHandler可以对应多个ChannelHandlerContext。当一个ChannelHandler使用Sharable注解修饰且添加同一个实例对象到不用的Channel时,只有一个ChannelHandler实例对象,但每个Channel中都有一个ChannelHandlerContext对象实例与之对应。

    请戳GitHub原文: https://github.com/wangzhiwubigdata/God-Of-BigData关注公众号,内推,面试,资源下载,关注更多大数据技术~大数据成神之路~预计更新500+篇文章,已经更新60+篇~
复制代码

Netty源码解析4-Handler综述相关推荐

  1. Netty 源码解析系列-服务端启动流程解析

    netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...

  2. Netty源码解析之内存管理-PooledByteBufAllocator-PoolArena

      PooledByteBufAllocator是Netty中比较复杂的一种ByteBufAllocator , 因为他涉及到对内存的缓存,分配和释放策略,PooledByteBufAllocator ...

  3. Netty源码解析-Netty内存泄露检测

    前言: 在前一篇文章中,我们介绍了ByteBuf的引用计数器的使用,基本所有的ByteBuf都有相关计数的功能,那么这个计数有什么用呢. 实际主要就是做内存泄露检测用的.本文就其如何做检测来进行说明. ...

  4. 【Netty源码解析】Netty核心源码和高并发、高性能架构设计精髓

    Netty线程模型图 Netty线程模型源码剖析图 图链接:https://www.processon.com/view/link/5dee0943e4b079080a26c2ac Netty高并发高 ...

  5. Netty源码解析1-Buffer

    大数据成神之路系列: 请戳GitHub原文: github.com/wangzhiwubi- 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合 Java高级特 ...

  6. Netty源码解析8-ChannelHandler实例之CodecHandler

    请戳GitHub原文: github.com/wangzhiwubi- 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合 Java高级特性增强-多线程 Jav ...

  7. 深入netty源码解析之一数据结构

    Netty是一个异步事件驱动的网络应用框架,它适用于高性能协议的服务端和客户端的快速开发和维护.其架构如下所示: 其核心分为三部分, 最低层为支持零拷贝功能的自定义Byte buffer: 中间层为通 ...

  8. Netty源码解析(八) —— channel的read操作

    客户端channel在建立连接之后会关注read事件,那么read事件在哪触发的呢? NioEventLoop中 /*** 读事件和 accept事件都会经过这里,但是拿到的unsafe对象不同 所以 ...

  9. netty源码解析(三)recycler

    recycler类是netty中对象的缓存利用的类, 一.普通用法如下: public class RecyclerTest {private static final Recycler<Use ...

最新文章

  1. javascript调用dll_Blazor条码识别:Web中运行C#和JavaScript
  2. 怎样办理软件著作权登记
  3. android判断点击次数_Android应用统计-使用时长及次数统计(一)
  4. 信息学奥赛一本通 1061:求整数的和与均值 | OpenJudge NOI 1.5 04
  5. OpenCV精进之路(二十一):实例——去除发票上的印章
  6. 项目总结:初稿与定稿,方向相差180度
  7. 什么是重载?重载的定义是什么?如何判断方法是否重载?最详细解答博文
  8. 计算机二级第24套Excel解析,Excel | 操作题第 24 套
  9. 基于QT实现的图书室管理系统
  10. 深度阅读----人工智能简史及其思维辩证
  11. 系统学习Spring之Spring in action(三)
  12. CMS内容管理系统(含小程序,Uni APP) 搭建
  13. net_device详解
  14. stm32f10x.h解析
  15. 全栈工程师如何逆袭?
  16. Unity3D使用LitJson.dll解析报错问题
  17. 计算机课玩手机检讨500,上学带手机检讨书500字范文(精选6篇)
  18. 黑苹果0005——我的config文件(笔记本 intel HD630)
  19. 库卡机器人坐标手势_在工具坐标系中移动库卡机器人
  20. matlab中0.1见方,square,square怎么读?

热门文章

  1. java管程 实现,Java中的管程模型
  2. pmp考试用计算机,PMP是计算机类考试吗
  3. php 位运算与权限,PHP巧妙利用位运算实现网站权限管理的方法
  4. python3基础知识梳理(一)
  5. mui后端开发php,PHP解决mui中ajax的跨域问题
  6. adobexd怎么录屏_请问如何使用Adobe XD制作应用动效?
  7. 【 FPGA 】四位16进制的数码管动态显示设计
  8. 简单的成绩录入系统程序及分析以及思考
  9. 将中文日期转换成自己想要的格式如:2018年09月29日转换成2018-09-29
  10. [linux] shell脚本编程-ubuntu创建vsftpd服务