1、AOP的目的就是将核心关注点和横切关注点分离,实际上这就是一种分散关注(seperation of concerns)的思路:
下载地址:http://eclipse.org/aspectj
2、AspectJ:
pointcut :
*
..表示任何数量的字符包括任何数量的(.)
+ 描述指定类型的任何子类或者子接口
1.call(public * *(..)) 任意公共方法的调用;
2.execution(!static * *(..))任意非静态方法的执行;(
3.execution(public !static * *(..))任意公共非静态方法的执行。
call捕捉调用栈的信息,而execution捕捉已经执行的方法;
call切点不能捕捉超类的非静态方法,因为它们没有经过动态地分配;
经验告诉表明,如果你要捕捉的连接点已经实际地运行(比如代码跟踪),那么用execution;
如果你要捕捉一个特定的签名 方法用call。
advise:
before通知在匿名切点捕捉到连接点之前运行
after通知在匿名切点捕捉到各个连接点之后运行,无论程序是正常返回还是抛出异常
around通知可以取代被捕捉的连接点而执行它自己定义的逻辑,
程序原有的逻辑可以通过调用一个特定的方法proceed执行
thisJoinPoint变量:
thisJoinPoint可以被用来访问静态和动态信息,比如说参数等:thisJoinPoint.getArgs();
另外,它持有一个包括所有静态信息的对象,可以通过以下方法得到该对象的引用:thisJoinPoint.getStaticPart();
如果你仅需要关于连接点处的静态信息,你可能访问连接点的静态部分直接使用变量thisJoinPointStaticPart。
使用它将避 免运行时直接使用thisJoinPoint创建连接点对象。
例子:
public aspect ErrorHandlingAspect {
public pointcut executeHandler():
execution(* com.gameabc.ipad.handler..*.execute(..) );
Object around():executeHandler() {
boolean debug = logger.isDebugEnabled();
AmfMessage inMsg = (AmfMessage) thisJoinPoint.getArgs()[0];
if (debug) {
StringBuilder sb = new StringBuilder();
sb.append("[socket Handler Start] with args: ");
sb.append(StringUtils.join(thisJoinPoint.getArgs(), ","));
logger.debug(sb.toString());
}
Response response = ((MethodSignature)thisJoinPoint.getSignature()).getMethod().getAnnotation(Response.class);
if (response != null && "true".equals(response.value())) {
try {
inMsg = (AmfMessage) proceed();
} catch (BaseException be) {
if (debug) {
logger.error("[socket Handler] catch BaseException!", be);
}
inMsg.setPhase(AmfMessage.RESPONSE_FAILED_PHASE);
inMsg.setErrorCode(be.getErrorCode());
inMsg.setErrorMsg(be.getMessage());
inMsg.setData(null);
} catch (Throwable e) {
if (debug) {
logger.error("[socket Handler] catch Exception!", e);
}
inMsg.setPhase(AmfMessage.RESPONSE_FAILED_PHASE);
inMsg.setErrorCode(BaseException.FAIELD);
inMsg.setErrorMsg(e.getMessage());
inMsg.setData(null);
e.printStackTrace();
}
return inMsg;
} else {
proceed();
return null;
}
}
public static final int LONG_EXECUTION_MS = 1000;
private static Logger logger = Logger.getLogger(ErrorHandlingAspect.class);
}