/aspectjs

aspectjs切面编程

Primary LanguageJavaScriptMIT LicenseMIT

#aspectjs切面编程 aspectjs是一个给JavaScript增加切面功能的强大组件。这个项目起源于ecojs切面功能,但是为了让切面编程更好的发展,所以决定把这部分单独拿出来,让你可以单独使用切面功能。当然你在ecojs可以获得同样的功能,两个项目的功能会保持同步更新。

##切面概念

AOP(Aspect Oriented Programming)面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构以完善面向对象编程(OOP),AOP为开发者提供了一种描述横切关注点的机制,并能够自动将横切关注点织入到面向对象的软件系统中,从而实现了横切关注点的模块化。

方面/切面(Aspect):横切关注点的模块化,比日志组件。可以认为是增强、切入点的组合;在AOP中表示为“在哪里做和做什么集合”;

连接点(Joinpoint):表示需要在程序中插入横切关注点的扩展点,连接点可能是类初始化、方法执行、方法调用、字段调用或处理异常等等,aspectjs只支持方法执行连接点,在AOP中表示为“在哪里做”;

切入点(Pointcut):选择一组相关连接点的模式,即可以认为连接点的集合,在AOP中表示为“在哪里做的集合”;

增强(Advice):或称为增强在连接点上执行的行为,增强提供了在AOP中需要在切入点所选择的连接点处进行扩展现有行为的手段;包括前置增强(before advice)、后置增强 (after advice)、环绕增强 (around advice)等。在AOP中表示为“做什么”;

目标对象(Target Object):需要被织入横切关注点的对象,即该对象是切入点选择的对象,需要被增强的对象,从而也可称为“被增强对象”;在AOP中表示为“对谁做”;

##切面api

###切面 切面定义:new Aspect(aspectId,advice)

aspectId:切面的id,选填。

advice:通知,选填。

当一个参数都不传的时候是创建一个匿名切面。当有一个参数,但这个参数是对象,那么他是advice,这个切面也是匿名切面,如果是string,那么这个参数就是切面名称。

例子:

var statTimesFilter = new Aspect("statTimesFilter");

###通知 我们的通知有下面几种类型:before,after,throwing,around,[eventName]。eventName可以是任何事件名.通知可以在切面定义的时候传入,也可以以后定义。

通知定义:[aspectName].advice.[adviceName] = function(jointPoint)

jointPoint:这个连接点的数据对象。结构如下:

{
  context: context,  //目标对象
  contextName: Aspect.getClassName(context), //目标对象名字
  target: originTarget,  //切面针对的函数,在未加切面原来的样子
  targetName: targetName,//函数名字
  arguments: arguments,//函数参数
  result: "",          //函数返回的数据
  error: "",           //针对异常切面,返回的异常数据
  stop: false,         //用于阻断函数执行
  eventDatas: {}	   //key是某个特定事件切面的名称,value是事件传送的数据
}

例子:

statTimesFilter.advice.before = function(jointPoint){
	var context = jointPoint.context;
	var contextName = jointPoint.contextName;
	var target = jointPoint.target;
	var targetName = jointPoint.targetName;
    var arguments = jointPoint.arguments;
	this.startTime = new Date();
	this.escape = 0;
	console.log("统计开始时间:"+this.startTime);
	//用于控制代码是否停止
	// jointPoint.stop = true;
	jointPoint.arguments[0] ="change";
}

###连接点

切入点是一组连接点,用于连接目标对象和切面的。

切入点定义:pointCut(context,targetNames)

context:目标对象。

targetNames:目标对象上要被加上切面的方法名。类型是array或者string

参数可以是1个,也可以是两个。参数为1个的时候,且类型为array或者string,这个参数就是targetNames。如果是object,那么就是context,这个时候的targetNames为这个context上的所有方法。

例子:

var testObj ={
	f1:function(arg1){
		console.log(arg1)
		console.log("f1");
		if(this._eventAdvices&&this._eventAdvices["f1"]){ //这里是针对事件切面的
			var eventAdvice  = this._eventAdvices["f1"];
			var eventData = {aa:"111"};
			eventAdvice.emit("eventName",eventData);
		}
	}
}
statTimesFilter.pointCut(testObj,"f1");
statTimesFilter.pointCut(testObj,"f1");
testObj.f1("入参1");