摘要:在方法執(zhí)行后,再執(zhí)行函數(shù)函數(shù)在執(zhí)行時,接收的參數(shù)第一個是的返回值,之后的參數(shù)和傳給相同。的返回值源碼定義兩個出口定義一個可柯里化的函數(shù),柯里化成函數(shù)指向基于生成的類的實例,如上例的如果該函數(shù)是第一次切面化綁定,則包裝該函數(shù)。
系列文章:讀 arale 源碼之 class 篇
使用 Aspect,可以允許你在指定方法執(zhí)行的前后插入特定函數(shù)
before object.before(methodName, callback, [context])在 object[methodName] 方法執(zhí)行前,先執(zhí)行 callback 函數(shù).
callback 函數(shù)在執(zhí)行時,接收的參數(shù)和傳給 object[methodName] 相同。
dialog.before("show", function(a, b) { a; // 1 b; // 2 }); dialog.show(1, 2)after object.after(methodName, callback, [context])
在 object[methodName] 方法執(zhí)行后,再執(zhí)行 callback 函數(shù).
callback 函數(shù)在執(zhí)行時,接收的參數(shù)第一個是 object[methodName] 的返回值,之后的參數(shù)和傳給 object[methodName] 相同。
dialog.after("show", function(returned, a, b) { returned; // show 的返回值 a; // 1 b; // 2 }); dialog.show(1, 2);源碼
定義兩個出口
exports.before = function(methodName, callback, context) { return weave.call(this, "before", methodName, callback, context); }; exports.after = function(methodName, callback, context) { return weave.call(this, "after", methodName, callback, context); };
定義一個可柯里化的函數(shù) weave,柯里化成 after、before 函數(shù)
function weave(when, methodName, callback, context) { var names = methodName.split(/s+/); var name, method; while (name = names.shift()) { // this 指向基于 Base 生成的類的實例,如上例的 dialog method = getMethod(this, name); // 如果該函數(shù)(show)是第一次切面化綁定,則包裝該函數(shù)。 // 被包裝的函數(shù)在執(zhí)行前后都會觸發(fā)下面注冊的事件。 if (!method.__isAspected) { wrap.call(this, name); } // 注冊事件:例如 after:show 、 before:show . this.on(when + ":" + name, callback, context); } return this; }
如果沒有在實例中找到該方法(show),則拋出異常。
// 在實例中查找該方法,若沒有則拋出異常 function getMethod(host, methodName) { var method = host[methodName]; if (!method) { throw new Error("Invalid method name: " + methodName); } return method; }
定義一個包裝器函數(shù),被包裝的函數(shù)在執(zhí)行前后(before、after)都會觸發(fā)一個特定的函數(shù)
// 包裝器,使該函數(shù)(show)支持切面化 function wrap(methodName) { // 保存舊的方法,this 指向該對象(dialog) var old = this[methodName]; // 定義新的方法,并在舊方法之前觸發(fā) before 綁定的函數(shù),之后觸發(fā) after 綁定的函數(shù) this[methodName] = function() { var args = Array.prototype.slice.call(arguments); var beforeArgs = ["before:" + methodName].concat(args); // 觸發(fā) before 綁定的函數(shù),如果返回 false 則阻止原函數(shù) (show) 執(zhí)行 if (this.trigger.apply(this, beforeArgs) === false) return; // 執(zhí)行舊的函數(shù),并將返回值當作參數(shù)傳遞給 after 函數(shù) var ret = old.apply(this, arguments); var afterArgs = ["after:" + methodName, ret].concat(args); // 觸發(fā) after 綁定的函數(shù),綁定的函數(shù)的第一個參數(shù)是舊函數(shù)的返回值 this.trigger.apply(this, afterArgs); return ret; } // 包裝之后打個標記,不用再重復包裝了 this[methodName].__isAspected = true; }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/78207.html
摘要:下圖展示了這些概念的關聯(lián)方式通知切面的工作被稱為通知。切面在指定的連接點被織入到目標對象中。該注解表明不僅僅是一個,還是一個切面。 在軟件開發(fā)中,散布于應用中多處的功能被稱為橫切關注點(crosscutting concern)。通常來講,這些橫切關注點從概念上是與應用的業(yè)務邏輯相分離的(但是往往會直接嵌入到應用的業(yè)務邏輯之中)。把這些橫切關注點與業(yè)務邏輯相分離正是面向切面編程(AOP...
摘要:項目地址項目主頁基于和注解的輕量級容器,提供了依賴注入面向切面編程及異常處理等功能??稍谌我夤こ讨幸耄且粋€框架無關的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫類等保持兼容。 Rockerjs Core 項目地址 項目主頁 基于 TypeScript 和注解的輕量級IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個框架無...
摘要:項目地址項目主頁基于和注解的輕量級容器,提供了依賴注入面向切面編程及異常處理等功能。可在任意工程中引入,是一個框架無關的容器。模塊不依賴于任何框架,并與現(xiàn)有框架庫類等保持兼容。 Rockerjs Core 項目地址 項目主頁 基于 TypeScript 和注解的輕量級IoC容器,提供了依賴注入、面向切面編程及異常處理等功能。Rockerjs Core可在任意工程中引入,是一個框架無...
摘要:入門篇學習總結時間年月日星期三說明本文部分內容均來自慕課網(wǎng)。主要的功能是日志記錄,性能統(tǒng)計,安全控制,事務處理,異常處理等等。 《Spring入門篇》學習總結 時間:2017年1月18日星期三說明:本文部分內容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://git...
摘要:要實現(xiàn)的功能,無非就是把兩個部分串聯(lián)起來切面切點只要一個類的方法中含有切點,那說明這個方法需要被代理,插入切面,所以相應的就需要產生代理類。代碼實現(xiàn)作為準備工作,首先我們定義相應的注解類是類注解,表明這是一個切面類,包含了切面函數(shù)。 之前一篇文章分析了Java AOP的核心 - 動態(tài)代理的實現(xiàn),主要是基于JDK Proxy和cglib兩種不同方式。所以現(xiàn)在干脆把這個專題做完整,再造個簡...
閱讀 2335·2019-08-30 15:56
閱讀 3163·2019-08-30 13:48
閱讀 1185·2019-08-30 10:52
閱讀 1553·2019-08-29 17:30
閱讀 479·2019-08-29 13:44
閱讀 3713·2019-08-29 12:53
閱讀 1181·2019-08-29 11:05
閱讀 2725·2019-08-26 13:24