Netty源码分析之设计模式在Netty框架中的应用
如果你对设计模式不是很熟悉,建议补习一下设计模式再来阅读本章的内容。本章主要分析设计模式的应用案例,不对设计模式本身做详细讲解。1。1单例模式源码举例
单例模式要点回顾如下。
(1)一个类在任何情况下只有一个对象,并提供一个全局访问点。
(2)延迟创建。
(3)避免线程安全问题。
Netty中的单例模式应用非常广泛,单例模式本身也比较简单,下面列举MqttEncoder类,采用饿汉式单例的写法。饿汉式单例最大的优点就是简单,绝对线程安全。具体代码如下。
1。2策略模式源码举例
策略模式要点回顾如下。
(1)封装一系列可相互替换的算法家族。
(2)动态选择某一个策略。
Netty在根据CPU核数分配线程数量的一个优化时,如果是2的平方则采用PowerOfTwoEventExecutorChooser来创建EventExecutorChooser,如果不是2的平方则采用GenericEventExecutorChooser来创建EventExecutorChooser,这里用的是三元运算选择策略,具体代码如下。
1。3装饰者模式源码举例
装饰者模式要点回顾如下。
(1)装饰者和被装饰者实现同一个接口。
(2)装饰者通常继承被装饰者,同宗同源。
(3)动态修改、重载被装饰者的方法。
从Netty的ByteBuf类结构图可以看到,ByteBuf的直接实现类有五个,忽略WrappedByteBuf这个类,其实直接实现类有四个。为什么要忽略掉WrappedByteBuf呢?因为它是ByteBuf装饰者的基类,本身没有任何实现功能。来看WrappedByteBuf的代码,主要功能就是保存被装饰者的引用。
具体的装饰者,继承上面的装饰者的顶级类,在自己的构造函数中接收ByteBuf的类型的参数,并把它传递给它的父类,用户在调用装饰者时,会把创建的最上面的四种待装饰的组件类以构造方法的形式传递进去,整个体系就运行起来了。而且装饰者可以按照自己的需求重写父类的方法,或者在现在的基础上添加新的方法调用进行增强。例如UnreleasableByteBuf类,重写了release()方法,并返回false表示UnreleasableByteBuf不支持被释放。
再比如SimpLeakAwareByteBuf类,从字面意思来看,其实是一个内存泄露感知的ByteBuf,同样继承自WrappedByteBuf。从构造方法来看,其构造参数多了一个ResourceLeak,主要用于对内存泄露的跟踪。主要差异在于增加了release()方法,代码如下。
看到上面的代码,还是来关注release()方法。它调用release()方法,根据返回结果额外增加了一个资源泄露的监控行为。1。4观察者模式源码举例
观察者模式要点回顾如下。
(1)两个角色:观察者和被观察者。
(2)观察者订阅消息,被观察者发布消息。
(3)订阅则能收到消息,取消订阅则收不到消息。
Netty里面的观察者和被观察者模式一般用Promise和Future来实现。项目中用得比较多的一个方法就是channel。writeAndFlush()方法。当调用channel。writeAndFlush()方法的时候,实际上就是创建了一个被观察者ChannelFuture,来看源码。
writeAndFlush()方法的返回值是ChannelFuture。当调用ChannelFuture的addListener()方法的时候,其实就是往ChannelFuture中添加被一个ChannelPromise,继续往下跟踪源码。
上面的writeAndFlush()方法还有一个重载方法,其中一个参数就是ChannelPromise,通常情况下Future和Promise是成对出现的。我们发现ChannelPromise就是ChannelFuture的子类,在Promise中定义了非常多的回调方法,提供给用户去重载,用户用自己的逻辑通常实现各种Listener接口来重载达到回调通知的目的。1。5迭代器模式源码举例
迭代器模式要点回顾如下。
(1)实现迭代器接口。
(2)实现对容器中的各个对象逐个访问的方法。
Netty里面的CompositeByteBuf这个零拷贝的实现,就使用了迭代器模式。首先看一段代码。
这段代码把两个ByteBuf添加到一起,forEachByte就是实现了迭代器模式。那么为什么说它是零拷贝呢?
我们找到forEachByte()的实现,在AbstractByteBuf里面,有下面这样一段代码。
从readerIndex开始读,读到writeIndex。继续跟进forEachByteAsc0()方法,查看源码。
继续看getByte()方法的实现,找到CompositeByteBuf类的实现。
先找到Index对应的Component,然后迭代的时候直接返回Component的Byte内容,就实现了零拷贝。其他的ByteBuf如果迭代的话,可能会把所有的数据都拷贝一遍。1。6责任链模式源码举例
责任链是指多个对象都有机会处理同一个请求,从而避免请求的发送者和接收者之间的耦合关系。然后,将这些对象连成一条链,并且沿着这条链往下传递请求,直到有一个对象可以处理它为止。在处理过程中,每个对象只处理它自己关心的那一部分,不相关的部分可以继续往下传递,直到链中的某个对象不想处理,可以将请求终止或丢弃。
责任链模式要点回顾如下。
(1)需要有一个顶层责任处理接口。
(2)需要有动态创建链、添加和删除责任处理器的接口。
(3)需要有上下文机制。
(4)需要有责任终止机制。
Netty的Pipeline就是采用了责任链设计模式,底层采用双向链表的数据结构,将链上的各个处理器串联起来。客户端每一个请求到来,Netty都认为是Pipeline中所有的处理器都有机会处理它。因此,对于入栈的请求,全部从头节点开始往后传播,一直传播到尾节点(来到尾节点的msg才会被释放)。
Netty的责任链模式中的组件如下。
(1)责任处理器接口ChannelHandler。
(2)添加删除责任处理器的接口ChannelPipeline。
(3)上下文组件ChannelHandlerContext,可获得用户记需要的数据。
(4)终止责任链的ctx。fireXXX()方法,可终止传播事件。
Pipeline中所有的Handler为顶级抽象接口,它规定了所有的Handler统一要有添加、移除、异常捕获的行为。
Pipeline中的Handler被封装进了上下文中。通过上下文可以轻松获取当前节点所属的Channel及其线程执行器。
责任终止机制包括如下内容。
(1)Pipeline中的任意一个节点,只要不手动往下传播,这个事件就会在当前节点终止传播。
(2)对于入栈数据,默认会传递到尾节点进行回收,如果不进行下一步传播,事件就会终止在当前节点。
(3)对于出栈数据,头节点使用Unsafe对象,把数据写回客户端也意味着事件的终止。
底层事件的传播使用的就是针对链表的操作,如AbstractChannelHandlerContext类的findContextInbound()方法。
1。7工厂模式源码举例
工厂模式的要点就是将创建对象的逻辑封装起来。
我们最先接触ReflectiveChannelFactory就是专门用来创建Channel的工厂,它接收一个Class对象,然后调用Class的newInstance()方法,将创建好的对象返回去。
Netty中的设计模式应用非常多,这里不再一一列举,希望大家花时间去探索,这样才能够有更多的收获。本章旨在为大家打开深入探索Netty的大门,有不妥之处请纠正交流。
芙蓉国评论丨领悟一号文件激活人才流量张若彤日前,中央一号文件中共中央国务院关于做好2023年全面推进乡村振兴重点工作的意见发布。文件指出,要实施乡村振兴人才支持计划,组织引导教育卫生科技文化社会工作精神文明建设等领域
在中国立春要躲春,这三种人真的要躲春吗?到底有没有道理立春要躲春,不在床上睡是中国传统文化中关于立春习俗的一句谚语。在中国,每年的立春都是农历二月初一,也是二十四节气之一。立春之后,气温逐渐回暖,草木开始萌芽生长,大地开始复苏,万物开
张镇麟,为何能成为中国男篮最好的小前锋?三大定律告诉你答案头条创作挑战赛张镇麟为什么能成为中国男篮最好的小前锋?一是基因好,身体天赋高!二是运气好,拿到败方MVP。三是努力好学,远赴美国追梦,虽然没有被选上,但是敢去就是好样的。都说成功三
足坛劲爆一夜国米13绝平里尔,中国U20女足60北京时间3月11日凌晨,五大联赛和U20女足亚洲杯预选赛结束了多场关键对决,国际米兰在意甲第26轮12爆冷输给了斯佩齐亚,里昂在法甲第27轮33客场绝平里尔,波鸿在德甲第24轮20
55载,400星!一起回顾中国空间事业光辉历程3月10日,我国在太原卫星发射中心使用长征四号丙运载火箭,成功将天绘六号AB星发射升空,卫星顺利进入预定轨道,发射任务获得圆满成功。这也是中国空间技术研究院研制并成功发射的第400
若这样,越南泰国缅甸柬埔寨更羡慕中国给老挝修的中老铁路老挝是一个夹在东南亚中间的内陆国家,去哪都近。中老铁路沿线有漂亮的景色!老挝23万平方公里,清除完五十多年前美国在胡志明小道投掷的未爆的航空炸弹后,老挝现有人口700多万,人口翻番
中国第一大淡水湖,现在快干透了!也许你曾徜徉于蓼子花海的美丽芬芳而依依不舍也许你曾难掩碧波褪去后看见落星墩全貌的喜悦也许你曾沉浸于鄱阳湖滩涂草原上的欢乐嬉戏。但是也许你并不知道,在这些美丽与欢乐的背后,是白鹤灰鹤
中国玄学与现代科学哪个才是宇宙的真理?中国玄学与现代科学哪个才是宇宙的真理人类对于宇宙的认知可以追溯到古代,而对于宇宙的探索则从一开始便有了形态各异的方式和方法。在古代中国,玄学作为一种重要的思想流派,对于宇宙和自然界
饮食小常识1饮食4忌利长寿长寿者的一个共同特点就是饮食有节。要长寿,饮食要注意四忌忌过饥过饱一个人如果没有足够的营养,机体的精气津液必亏虚乏竭,就会严重影响健康。相反,食之过多,暴饮暴食对健
联想为拯救者Y9000P2023游戏本推出C140适配器140W功率IT之家是科技媒体中的老牌一哥了,我不仅每天都看,还会转载他家的笔记本新闻。手机笔电等数码新品的资讯,去他家的App和网站上看准没错。今天就向大家强烈推荐IT之家公众号,另外也建议
童年缺爱的人,长大后有这5种表现!图片来源记忆中的玛尼贺兰日更的第6天心当一个人从小缺爱的人,长大后会形成各种各样的性格,最典型的表现有这5种01。自卑常常觉得自己不够好,不敢直视别人的眼睛,不敢去人多的地方,怕别
联想成立半导体公司了,如果不换老总,你会支持它吗?支持!企业要根据行业特点,明确自身长项短板,制定发展战略目标,经营自主。决不能受社会舆论干扰,局外人说话不负责任。有道是江山易改,品性难移,还是这帮人,都是改汤不换药,一个老样。不
30岁,在北京月薪一万五能攒到钱吗?还好吧,15k,税后大概12k左右吧。下面来算算开销1。衣平均一个月600,其实不算多。2。食平均一个月2k基本伙食费。每周出去聚餐一次250,平均一个月1k,一共3k。3。住如果
在天津工作,年薪10万属于什么水平?能买哪儿的房?在天津工作,月薪10万属于什么水平?平均高一点的水平。要知道在今年1月公布的薪酬报告里,天津平均月工资为6978元,在全国排26名。按这个算得话,天津的平均年薪应该在83000多点
养娃与工作两不误,究竟多艰难?很难很难,这个时候是每一个母亲最难的时候。我闺女6个月到一周期间,我跟我老公两个人带着宝宝,一边上班一边工作,重点是我老公刚换工作,不熟悉,经常加班,而我自己,一边带孩子,一边上班
父母养孩子小难,还是孩子养父母老难?老话床头三日无孝子,自理期间供给吃喝,时不时的打个电话关心一下。好一点的能作到满足,但大多数马马胡胡,不少人是眼不见心不乱!病了有条件治,无条件应付。如果老人有点积余还可能多治疗,
快50的人了,没喝过茅台,算不算失败?作揖谢邀。和人生相比的话,茅台算个鸡毛。在我看来,茅台充其量也仅仅只是当下卖得有点贵的一款酒一件商品而已。退一万步说,生活只要过得充盈,没有虚度年华,哪怕真的一辈子消费不起一瓶茅台
一次性缴纳社保金12万,55岁以后每月领取一千多划算吗?一次性缴纳12万元,假设55岁每月领取1000元。这样一年领取1。2万元,需要10年领回本金。在一些人看来,似乎是食之有味,弃之可惜的鸡肋吧。毕竟现在一次性缴纳12万元,真的也是一
想在农村大集摆地摊卖老年手机,靠谱吗?我感觉不大靠谱,现在谁还用老年手机,很少了。农村老年人现在大多数也是用智能手机,而且都上微信,他们上微信可能不会打字,可很多人学会了语音。有的老年人儿女常期在外打工,智能手机有微信
DNF玩家晒出无天空5W物攻剑魂欲以80001W出售,网友直言至少卖8W,如何评价?大家都知道DNF的账号是非常贬值的,充值10W的账号能卖到1W就已经非常不错了,在加上由于买卖账号风险高的原因,DNF账号买卖一直以来都是非常忌惮的事情,买的怕被找回,卖的又怕价格
在移动互联网时代,消失的职业有哪些?首先消失的职业有小偷和贼。二三十年前,那些小偷和贼真是让人深恶痛绝,他们不劳而获,偷了人们辛苦赚来的财物。因为那时候人们都是现金交易,用的都是现金。最近十几年,人们出门不带现金了,
助听器有什么优缺点?各种外形助听器的特点听觉有道华南助听器20200408132306盒式助听器外形类似微型收音机。麦克风放大器和电池都放在一个盒里,配戴在胸前的口袋内,由一条细小的电线把助听器与附加