Netty源码解析4-Handler综述
请戳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接口。按照输入输出来分,分为ChannelInboundHandler
、ChannelOutboundHandler
两大类
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综述相关推荐
- Netty 源码解析系列-服务端启动流程解析
netty源码解析系列 Netty 源码解析系列-服务端启动流程解析 Netty 源码解析系列-客户端连接接入及读I/O解析 五分钟就能看懂pipeline模型 -Netty 源码解析 1.服务端启动 ...
- Netty源码解析之内存管理-PooledByteBufAllocator-PoolArena
PooledByteBufAllocator是Netty中比较复杂的一种ByteBufAllocator , 因为他涉及到对内存的缓存,分配和释放策略,PooledByteBufAllocator ...
- Netty源码解析-Netty内存泄露检测
前言: 在前一篇文章中,我们介绍了ByteBuf的引用计数器的使用,基本所有的ByteBuf都有相关计数的功能,那么这个计数有什么用呢. 实际主要就是做内存泄露检测用的.本文就其如何做检测来进行说明. ...
- 【Netty源码解析】Netty核心源码和高并发、高性能架构设计精髓
Netty线程模型图 Netty线程模型源码剖析图 图链接:https://www.processon.com/view/link/5dee0943e4b079080a26c2ac Netty高并发高 ...
- Netty源码解析1-Buffer
大数据成神之路系列: 请戳GitHub原文: github.com/wangzhiwubi- 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合 Java高级特 ...
- Netty源码解析8-ChannelHandler实例之CodecHandler
请戳GitHub原文: github.com/wangzhiwubi- 更多文章关注:多线程/集合/分布式/Netty/NIO/RPC Java高级特性增强-集合 Java高级特性增强-多线程 Jav ...
- 深入netty源码解析之一数据结构
Netty是一个异步事件驱动的网络应用框架,它适用于高性能协议的服务端和客户端的快速开发和维护.其架构如下所示: 其核心分为三部分, 最低层为支持零拷贝功能的自定义Byte buffer: 中间层为通 ...
- Netty源码解析(八) —— channel的read操作
客户端channel在建立连接之后会关注read事件,那么read事件在哪触发的呢? NioEventLoop中 /*** 读事件和 accept事件都会经过这里,但是拿到的unsafe对象不同 所以 ...
- netty源码解析(三)recycler
recycler类是netty中对象的缓存利用的类, 一.普通用法如下: public class RecyclerTest {private static final Recycler<Use ...
最新文章
- javascript调用dll_Blazor条码识别:Web中运行C#和JavaScript
- 怎样办理软件著作权登记
- android判断点击次数_Android应用统计-使用时长及次数统计(一)
- 信息学奥赛一本通 1061:求整数的和与均值 | OpenJudge NOI 1.5 04
- OpenCV精进之路(二十一):实例——去除发票上的印章
- 项目总结:初稿与定稿,方向相差180度
- 什么是重载?重载的定义是什么?如何判断方法是否重载?最详细解答博文
- 计算机二级第24套Excel解析,Excel | 操作题第 24 套
- 基于QT实现的图书室管理系统
- 深度阅读----人工智能简史及其思维辩证
- 系统学习Spring之Spring in action(三)
- CMS内容管理系统(含小程序,Uni APP) 搭建
- net_device详解
- stm32f10x.h解析
- 全栈工程师如何逆袭?
- Unity3D使用LitJson.dll解析报错问题
- 计算机课玩手机检讨500,上学带手机检讨书500字范文(精选6篇)
- 黑苹果0005——我的config文件(笔记本 intel HD630)
- 库卡机器人坐标手势_在工具坐标系中移动库卡机器人
- matlab中0.1见方,square,square怎么读?
热门文章
- java管程 实现,Java中的管程模型
- pmp考试用计算机,PMP是计算机类考试吗
- php 位运算与权限,PHP巧妙利用位运算实现网站权限管理的方法
- python3基础知识梳理(一)
- mui后端开发php,PHP解决mui中ajax的跨域问题
- adobexd怎么录屏_请问如何使用Adobe XD制作应用动效?
- 【 FPGA 】四位16进制的数码管动态显示设计
- 简单的成绩录入系统程序及分析以及思考
- 将中文日期转换成自己想要的格式如:2018年09月29日转换成2018-09-29
- [linux] shell脚本编程-ubuntu创建vsftpd服务