日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

dojo/aspect源码解析

發布時間:2024/4/13 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 dojo/aspect源码解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  dojo/aspect模塊是dojo框架中對于AOP的實現。關于AOP的詳細解釋請讀者另行查看其它資料,這里簡單復習一下AOP中的基本概念:

  • 切面(Aspect):其實就是共有功能的實現。如日志切面、權限切面、事務切面等。
  • 通知(Advice):是切面的具體實現。以目標方法為參照點,根據放置的地方不同,可分為前置通知(Before)、后置通知(After)與環繞通知(Around)。
  • 連接點(Joinpoint):就是程序在運行過程中能夠插入切面的地點。
  • 目標對象(Target):就是那些即將切入切面的對象,也就是那些被通知的對象。這些對象中已經只剩下干干凈凈的核心業務邏輯代碼了,所有的共有功能代碼等待AOP容器的切入。
  • 代理對象(Proxy):將通知應用到目標對象之后被動態創建的對象。可以簡單地理解為,代理對象的功能等于目標對象的核心業務邏輯功能加上共有功能。代理對象對于使用者而言是透明的,是程序運行過程中的產物。
  • 織入(Weaving):將切面應用到目標對象從而創建一個新的代理對象的過程。這個過程可以發生在編譯期、類裝載期及運行期,當然不同的發生點有著不同的前提條件。譬如發生在編譯期的話,就要求有一個支持這種AOP實現的特殊編譯器;發生在類裝載期,就要求有一個支持AOP實現的特殊類裝載器;只有發生在運行期,則可直接通過Java語言的反射機制與動態代理機制來動態實現。
  •   生成代理對象的過程可以按照下圖理解:

      

      

      dojo/aspect模塊代碼主要分為兩部分:

    • advise方法,通過使用閉包跟鏈式模型來構造“通知”鏈。 "use strict";var undefined, nextId = 0;function advise(dispatcher, type, advice, receiveArguments){var previous = dispatcher[type];var around = type == "around";var signal;if(around){var advised = advice(function(){return previous.advice(this, arguments);});signal = {remove: function(){if(advised){advised = dispatcher = advice = null;}},advice: function(target, args){return advised ?advised.apply(target, args) : // called the advised functionprevious.advice(target, args); // cancelled, skip to next one }};}else{// create the remove handlersignal = {remove: function(){if(signal.advice){var previous = signal.previous;var next = signal.next;if(!next && !previous){delete dispatcher[type];}else{if(previous){previous.next = next;}else{dispatcher[type] = next;}if(next){next.previous = previous;}}// remove the advice to signal that this signal has been removeddispatcher = advice = signal.advice = null;}},id: nextId++,advice: advice,receiveArguments: receiveArguments};}if(previous && !around){if(type == "after"){// add the listener to the end of the list// note that we had to change this loop a little bit to workaround a bizarre IE10 JIT bugwhile(previous.next && (previous = previous.next)){}previous.next = signal;signal.previous = previous;}else if(type == "before"){// add to beginningdispatcher[type] = signal;signal.next = previous;previous.previous = signal;}}else{// around or first one just replacesdispatcher[type] = signal;}return signal;} View Code
    • aspect方法,這個函數返回一個閉包。閉包的作用是將“通知”方法織入到目標函數中,java中運行時通過反射的方式來織入,而js中通過動態更改目標函數來實現織入過程,這時調用該方法可以使切面函數與業務邏輯同時進行。 function aspect(type){return function(target, methodName, advice, receiveArguments){var existing = target[methodName], dispatcher;if(!existing || existing.target != target){// no dispatcher in placetarget[methodName] = dispatcher = function(){var executionId = nextId;// before advicevar args = arguments;var before = dispatcher.before;while(before){args = before.advice.apply(this, args) || args;before = before.next;}// around adviceif(dispatcher.around){var results = dispatcher.around.advice(this, args);}// after advicevar after = dispatcher.after;while(after && after.id < executionId){if(after.receiveArguments){var newResults = after.advice.apply(this, args);// change the return value only if a new value was returnedresults = newResults === undefined ? results : newResults;}else{results = after.advice.call(this, results, args);}after = after.next;}return results;};if(existing){dispatcher.around = {advice: function(target, args){return existing.apply(target, args);}};}dispatcher.target = target;}var results = advise((dispatcher || existing), type, advice, receiveArguments);advice = null;return results;};} View Code

      ?

      注意:dojo的處理過程中并不生成代理對象,而是直接更改原有的對象的方法。

      關于aspect.after方法(before方法與其類似)的解釋請看這篇文章:Javascript事件機制兼容性解決方案;aspect.around的由來在這篇文章Javascript aop(面向切面編程)之around(環繞)里有其一步步的演化過程。

      本文給出aspect模塊調用后的示意圖:

      before與after函數:

      

      around函數:

      

    var advised = advice(function(){return previous.advice(this, arguments);});signal = {remove: function(){if(advised){advised = dispatcher = advice = null;}},advice: function(target, args){return advised ? //一旦調用remove,adviced變為空,便會跳過本次環繞通知,進入上一層的advice方法。advised.apply(target, args) : // called the advised functionprevious.advice(target, args); // cancelled, skip to next one }};

      可以看到around函數中借用閉包形成環繞函數鏈。這里調用remove方法后并沒有像before跟after中將通知方法徹底移除,注冊過的環繞方法仍然會存在內存中,所以這個方法無法移除環繞通知,僅僅是避免了在函數鏈中執行它而已。內存無法釋放,不建議使用太多。

    ?

    總結

    以上是生活随笔為你收集整理的dojo/aspect源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 成 年 人 黄 色 大 片大 全 | 成人中文字幕在线观看 | 国内久久久 | 国产精品久久久久久久久久久久久 | 性xxxx欧美老肥妇牲乱 | 日本肉体xxxx裸体137大胆图 | 久久久亚洲欧洲 | 国内久久久久 | www.黄色. | 国产素人在线观看 | 三级在线视频 | 亚洲精品88| 狼人av在线| 亚洲码欧美码一区二区三区 | 国产黄色影院 | 亚洲欧美一区二区视频 | 91口爆一区二区三区在线 | 在线日韩一区 | 中国毛片在线 | 三上悠亚 电影 | 国产精品扒开腿做爽爽 | 国产真实偷伦视频 | 少妇特黄一区二区三区 | 五月婷婷在线观看 | 国产黄a三级 | 黄色网页网站 | 女同中文字幕 | 91网站免费入口 | av解说在线观看 | 久久99综合| 精品人妻一区二区三区四区在线 | 实拍澡堂美女洗澡av | 美女久久精品 | 久久成人人人人精品欧 | 欧美一区二区视频在线观看 | 日本少妇一级片 | 国产第20页| 超碰在线资源 | 日韩中文字幕高清 | 91草草草 | 久久成人免费电影 | 精品久久久久久久久久久久久久久 | 51免费看成人啪啪片 | 欧美亚洲一区二区三区四区 | 国产精品无码专区av在线播放 | 亚洲欧美乱日韩乱国产 | 亚洲一区二区三区免费视频 | 国产人妖网站 | 春宵av| 成人av网址在线 | 国产又粗又黄又爽视频 | 免费观看国产视频 | 国产chinesehd精品露脸 | 久久天天干| 久久午夜片 | 天天热天天干 | 婷婷色站 | 久久久久99精品成人片我成大片 | 进去里片欧美 | 日韩成人在线观看视频 | 中文字幕在线观看线人 | 中文字幕人妻丝袜二区 | 国产精品久久久久久久久久直播 | 欧美在线视频你懂的 | 久草国产精品 | 久久久久亚洲色欲AV无码网站 | 日韩资源网| 亚洲视频黄色 | 久久久电影 | bl动漫在线观看 | 亚洲精品在线免费 | 粉豆av | 韩日在线| 久久老司机精品视频 | 97精品一区 | avt天堂网| 日本一区二区免费在线 | 五月精品| 亚洲最新av网站 | 性xxxxx大片免费视频 | 天天躁日日躁狠狠躁伊人 | 中文字幕一区二区三区人妻 | 黄色香蕉视频 | 天天干视频在线 | 99免费精品 | 成人av色| 美女张开双腿让男人捅 | 干操网 | 国产高清露脸 | 久操精品视频 | 性视频一区 | 91麻豆精品视频 | 中文字字幕在线中文 | 午夜国产一区二区 | 激情综合五月天 | 99久久久国产精品 | 国产在视频线精品视频 | 色臀av | 久久久久久18 |