這篇文章主要介紹“handler在pipeline當(dāng)如何存儲(chǔ)”,在日常操作中,相信很多人在handler在pipeline當(dāng)如何存儲(chǔ)問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”handler在pipeline當(dāng)如何存儲(chǔ)”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
為烏什等地區(qū)用戶(hù)提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及烏什網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為網(wǎng)站制作、成都做網(wǎng)站、烏什網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶(hù)提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶(hù)的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
今天解決2個(gè)問(wèn)題,
1、handler在pipeline當(dāng)中究竟是如何存儲(chǔ)的;
2、在遍歷handler的過(guò)程中,會(huì)根據(jù)event的不同,調(diào)用不同的handler,這一點(diǎn)是如何實(shí)現(xiàn)的。
先研究第一個(gè)問(wèn)題:
TailHandler tailHandler = new TailHandler();
tail = new DefaultChannelHandlerContext(this, null, generateName(tailHandler), tailHandler);
HeadHandler headHandler = new HeadHandler(channel.unsafe());
head = new DefaultChannelHandlerContext(this, null, generateName(headHandler), headHandler);
head.next = tail;
tail.prev = head;
這是DefaultChannelPipeline構(gòu)造函數(shù)當(dāng)中的一段代碼,我們之前提到過(guò),在pipeline當(dāng)中存在一個(gè)雙向鏈表,這里就是把雙向鏈表的頭和尾進(jìn)行了初始化。
之后我們通過(guò)addlast方法向pipeline當(dāng)中添加handler,
DefaultChannelHandlerContext prev = tail.prev;
newCtx.prev = prev;
newCtx.next = tail;
prev.next = newCtx;
tail.prev = newCtx;
這里就是把一個(gè)新的handler加入到雙向鏈表當(dāng)中去。
另一個(gè)問(wèn)題,雙向鏈表當(dāng)中的元素究竟是什么,
DefaultChannelHandlerContext newCtx =
new DefaultChannelHandlerContext(this, invoker, name, handler);
需要看這個(gè),簡(jiǎn)單理解,把handler放到了一個(gè)新的 DefaultChannelHandlerContext 當(dāng)中。那么它的作用究竟是什么呢?
通過(guò)對(duì)代碼的研究, DefaultChannelHandlerContext其實(shí)是一個(gè)動(dòng)態(tài)代理類(lèi),而我們的各個(gè)handler,就是被代理的類(lèi)。這里有兩點(diǎn)需要解釋一下。先看下面這段代碼
@Override
public ChannelFuture write(Object msg, ChannelPromise promise) {
DefaultChannelHandlerContext next = findContextOutbound(MASK_WRITE);
next.invoker.invokeWrite(next, msg, promise);
return promise;
}
首先,不要被write方法所迷惑,這個(gè)方法里面確實(shí)執(zhí)行的write的動(dòng)作,以及write當(dāng)中所包含的encode的動(dòng)作。但是請(qǐng)注意,這個(gè)write動(dòng)作,并不是當(dāng)前元素的write,而是鏈表當(dāng)中下一個(gè)元素當(dāng)中的handler的write,在handler的write方法的末尾,會(huì)執(zhí)行next.write,這里又會(huì)執(zhí)行再下一個(gè)元素當(dāng)中的handler的write。依次類(lèi)推,實(shí)現(xiàn)了鏈表的遍歷。
其次:不要被invoke所迷惑,這里并沒(méi)有用到j(luò)ava的反射機(jī)制,因?yàn)?不論你傳入什么樣的handler,都來(lái)自ChannelHandler這個(gè)統(tǒng)一的老祖宗。按需要調(diào)用不同的方法即可。跟反射一毛錢(qián)關(guān)系都沒(méi)有。
然后是第二個(gè)問(wèn)題:
首先明確一個(gè)概念:所有的handler來(lái)自同一個(gè)祖宗ChannelHandler ,而 ChannelHandler 當(dāng)中的不同方法,對(duì)應(yīng)了netty當(dāng)中各個(gè)不同的事件。
我們?cè)诔跏蓟痓ootstrap的時(shí)候,加入了很多個(gè)handler,有些負(fù)責(zé)下行的decode,有些負(fù)責(zé)上行的encode,我們當(dāng)然希望,下行的時(shí)候,只進(jìn)入下行相關(guān)的handler,上行的時(shí)候,只進(jìn)入上行相關(guān)的handler。那么具體是怎么做到的呢?看下面這段代碼,鑒于篇幅問(wèn)題,只摘錄了其中一段:
if (handlerType.getMethod(
"handlerAdded", ChannelHandlerContext.class).isAnnotationPresent(Skip.class)) {
flags |= MASK_HANDLER_ADDED;
}
在構(gòu)造一個(gè) DefaultChannelHandlerContext,會(huì)有這樣的一段代碼,我們可以這樣理解這段語(yǔ)句:根據(jù)handler當(dāng)中不通方法的注解,來(lái)判定當(dāng)發(fā)生某個(gè)event的時(shí)候,該方法是否執(zhí)行。
ChannelHandlerAdapter 是 ChannelHandler 一個(gè)最基礎(chǔ)的實(shí)現(xiàn),我們看一下 ChannelHandlerAdapter 的代碼,會(huì)發(fā)現(xiàn),每一個(gè)方法頭部,都會(huì)有一個(gè)@Skip的注解。也就是說(shuō),默認(rèn)情況下,每一個(gè)方法都不會(huì)被執(zhí)行。而在 ChannelHandlerAdapter 的子孫當(dāng)中,Override了某一個(gè)方法, @Skip 就沒(méi)有了。那么這個(gè)handler的這個(gè)方法,就會(huì)被執(zhí)行。
至于具體的判定過(guò)程,可以參照另一個(gè)篇文章android edittext.setInputType,當(dāng)中按位進(jìn)行設(shè)置的思想。
到此,關(guān)于“handler在pipeline當(dāng)如何存儲(chǔ)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
分享文章:handler在pipeline當(dāng)如何存儲(chǔ)
本文鏈接:http://chinadenli.net/article10/gpcedo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、App設(shè)計(jì)、服務(wù)器托管、網(wǎng)站設(shè)計(jì)、微信小程序、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)