Unnamed AOP
一个 js 版的 aop 库, 能够无入侵的增加和改变函数或方法的行为.
基本概念
面向切面编程
通知(Advice)
在函数/方法执行的特定时机执行指定的逻辑. 主要有以下几个类型的通知:
- before: 在函数/方法执行前调用指定逻辑
- after: 在函数/方法执行后调用指定逻辑, 无论函数/方法是否执行成功
- afterReturning: 在函数/方法执行成功后调用指定逻辑
- afterThrowing: 在方法抛出异常后调用指定逻辑
- around: 在函数/方法调用之前和调用之后执行自定义的指定逻辑
切点(PointCut/Matcher)
切点(连接点筛选)功能, 为 string, RegExp, Function 三个类型之一, 指定符合匹配条件的方法才应用特定的通知逻辑
切面(Aspect/Advisor)
切面是通知和切点的结合, 通知和切点共同定义了切面的全部内容 - 是什么, 在何时和何处完成功能.
Advisor = // 切点/匹配器, 为字符串,正则,函数三种, 见 PointCut/Matcher matcher: Matcher // 通知对象, 拥有 before, afterReturning, afterThrowing, after, around 中一个或多个方法 advices: { //... }, { // ... }, { // ... }, { // ... }, { // ... } }}
安装
node
npm install uaop
Browser global
模块环境
; // es6// var aop = require('uaop'); // AMD/CMD// window.uaop // global
快速使用
; // es6 { console;} ;} // 函数拦截let proxyFunc = aop; ; // 对象拦截let obj = doSomething;let proxyObj = aop;proxyObj; // 类拦截 { console; } let ProxyClass = aop;let instance = ;instance;
API
Function API
提供针对函数执行拦截的API
before(functionToAdvise, beforeFunction)
返回一个新的函数, 执行逻辑为, 在 functionToAdvise 函数执行前, 执行 beforeFunction, beforeFunction 接收与 functionToAdvise 一致的参数
除非抛异常, 否则不会中断函数的执行
var { console;};var advisedFunction = aop; // log:// arguments length: 3// functionToAdvise exec;
afterReturning(functionToAdvise, afterReturningFunction)
返回一个新的函数, 执行逻辑为, 在 functionToAdvise 函数正常返回后, 执行 afterReturningFunction, afterReturningFunction 接收 functionToAdvise 执行后的返回结果作为唯一参数, 不影响返回结果.
var { console; return 'functionToAdvise';};var advisedFunction = aop; // log:// functionToAdvise exec// return value: functionToAdvise;
afterThrowing(functionToAdvise, afterThrowingFunction)
返回一个新的函数, 执行逻辑为, 在 functionToAdvise 函数抛出异常时, 执行 afterThrowingFunction, afterThrowingFunction 接收 functionToAdvise 抛出的异常对象作为唯一参数.
通知不会吞噬原有异常, 会在 afterThrowingFunction 执行完毕后, 抛出原有异常
var { console; ifthrowError throw 'functionToAdvise error'; };var advisedFunction = aop; // log:// functionToAdvise exec; // log:// functionToAdvise exec// execption: functionToAdvise error;
after(functionToAdvise, afterFunction)
返回一个新的函数, 执行逻辑为, 在 functionToAdvise 函数正常返回或抛出异常时, 执行 afterFunction
通知不会吞噬原有异常, 会在 afterFunction 执行完毕后, 抛出原有异常
var { ifthrowError console; throw 'error'; console;};var advisedFunction = aop; // log:// functionToAdvise normal exec// after functionToAdvise; // log:// functionToAdvise exception// after functionToAdvise;
around(functionToAdvise, aroundFunction)
返回一个新的函数, 执行逻辑为, 执行 aroundFunction, aroundFunction 接收一个 ProceedingJoinPoint 对象作为参数, 调用其 proceed/proceedApply 方法将执行 functionToAdvise.
var { console; return 'functionToAdvise return value';};var advisedFunction = aop; // log:// before functionToAdvise exec// functionToAdvise exec arguments: 1,2,3// functionToAdvise exec arguments: 1,2// functionToAdvise exec result: functionToAdvise return value// after functionToAdvise exec;
ProceedingJoinPoint
joinPoint = // 函数被调用时的上下文 target: Object // 传给外层函数的参数 args: Array // 原方法名或函数名 method: string // 被调用时, 会调用被拦截的原函数, 并传入原始参数 proceed: Function // 被调用时, 会调用被拦截的原函数, 首个参数为被拦截函数要执行时的上下文, 第二个参数为要传递给被拦截函数的参数数组 proceedApply: Function
createFunctionProxy(functionToAdvise, advices)
创建一个组装了多个通知行为的函数代理, advices 为拥有 before, afterReturning, afterThrowing, after, around 中一个或多个方法的对象.
Object Method API
提供针对对象方法的拦截。
每个拦截接口都接收三个参数:被拦截对象,方法匹配规则 matcher,通知执行函数。
matcher 可为 string, RegExp, Function 的任意一种,为 Function 时,接收被拦截对象和当前方法名作为参数,执行结果返回 true 时,匹配成功,会对该方法执行拦截。
每个拦截接口都会返回一个原对象的代理对象,代理对象会针对符合匹配规则的方法封装,根据通知类型,在方法执行的不同阶段,执行相关的通知逻辑。
注:原对象不受任何影响
before(objectToAdvise, matcher, beforeFunction)
返回一个新的代理对象, 在 matcher 匹配的方法执行前,会执行 beforeFunction,beforeFunction 接收匹配方法执行时的参数
除非抛异常, 否则不会中断匹配方法的执行
var toAdvise = { console; }; var advisedObject = aop; // log:// before method exec// a// method execadvisedObjectmethod'a'; // log:// method exectoAdvisemethod'a';
afterReturning(objectToAdvise, matcher, afterReturningFunction)
返回一个新的代理对象, 在 matcher 匹配的方法正常执行后, 执行 afterReturningFunction, afterReturningFunction 接收匹配方法执行后的返回结果作为唯一参数, 不影响返回结果.
var toAdvise = { console; return 'toAdivse method result'; }; var advisedObject = aop; // log:// method exec// return value: toAdivse method resultadvisedObjectmethod;
afterThrowing(objectToAdvise, matcher, afterThrowingFunction)
返回一个新的代理对象, 在 matcher 匹配的方法抛出异常后, 执行 afterThrowingFunction, afterThrowingFunction 接收匹配方法抛出的异常对象作为唯一参数.
通知不会吞噬原有异常, 会在 afterThrowingFunction 执行完毕后, 抛出原有异常
var toAdvise = { console; ifthrowError throw 'method error'; }; var advisedObject = aop; // log:// method execadvisedObjectmethod; // log:// method exec// execption: method erroradvisedObjectmethodtrue;
after(objectToAdvise, matcher, afterFunction)
返回一个新的代理对象, 在 matcher 匹配的方法正常返回或抛出异常后, 执行 afterFunction。
通知不会吞噬原有异常, 会在 afterFunction 执行完毕后, 抛出原有异常
var toAdvise = { ifthrowError console; throw 'error'; console; }; var advisedObject = aop; // log:// method exec// after method execadvisedObjectmethod; // log:// method exception// after method execadvisedObjectmethodtrue;
around(objectToAdvise, matcher, aroundFunction)
返回一个新的代理对象, 在 matcher 匹配的方法执行时, 执行 aroundFunction, aroundFunction 接收一个 ProceedingJoinPoint 对象作为参数, 调用其 proceed/proceedApply 方法将执行原方法.
var toAdvise = { console; return 'method return value'; }; var advisedObject = aop; // log:// before method exec// method exec arguments: 1,2,3// method exec arguments: 1,2// method exec result: method return value// after method execadvisedObjectmethod1 2 3;
createObjectProxy(objectToAdvise, matcher, advices)
创建一个组装了通知行为的对象代理, 会重写符合匹配规则的方法, 织入通知逻辑.
advice 拥有 before, afterReturning, afterThrowing, after, around 中一个或多个方法的对象.
ProceedingJoinPoint
同Function API 下的 ProceedingJoinPoint
Matcher
matcher 可以为以下三种类型:
- string 匹配拦截对象中属性名与 matcher 相等的方法。
- RegExp 匹配拦截对象中属性名符合 matcher 规则的方法。
- Function 匹配拦截对象中属性名符合 matcher 执行结果的方法, matcher 接收拦截对象和当前属性名称作为参数,返回 true 则表示匹配成功。
var toAdvise = {} {} {} {} {};// 将拦截 toAdvise.methodvar advisedObject = aop; // 将拦截 toAdvise.foo, toAdvise.foo1, toAdvise.foo2var advisedObject = aop; var { return name !== 'init';};// 将拦截 toAdvise.foo, toAdvise.foo1, toAdvise.foo2, toAdvise.methodvar advisedObject = aop;
Class Method API
提供针对Class方法拦截的 API
createClassProxy(Class, matcher, advices)
创建一个组装了通知行为的类代理, 会重写符合匹配规则的方法, 织入通知逻辑.
advice 拥有 before, afterReturning, afterThrowing, after, around 中一个或多个方法的对象.