本错误隔离策略是,捕获并处理所有可能从建议执行连接点抛出的 Throwable,这样它们就不会影响底层的应用程序。注意,建议执行切点匹配一 些 建议执行的连接点,因此这个方面将影响其他方面的行为。这种策略对于 before 和 after 建议都可以很好地工作,但是 around 建议实现错误隔离要复杂一点 儿 。如果在达到 proceed 语句之前抛出异常,那么我会仍然继续原来的连接点。 相 反,如果异常是在 proceed 语句处 抛出的,那么我会让异常通过而不会“隔离 ”它(即不吞掉它)。
因为在建议中没有调用 proceed 的连接点,因此不能编写像我需要的那样完 全一般化的建议。不过,可以用 Glassbox Inspector 的结构提供它所使用的那 种 around 建议的错误隔离。在 Glassbox Inspector 中惟一的 around 建议总 是构造一个工人对象,然后对它调用 execute() 模板方法,这个方法调用 doExecute() 以完成原来的连接点。因此我将处理由监视器中 (AbstractRequestMonitor 或者它的任何子类)的 helper 方法或者由在 execute 或者 doExecute() 中的调用返回的所有异常。清单 10 显示了我是如 何 扩展 Glassbox Inspector 以处理错误的:
清单 10. Glassbox Inspector 中的错误处理
public aspect ErrorHandling {
public pointcut scope() :
within(glassbox.inspector..*) && !within (ErrorHandling+);
public pointcut inMonitor() :
within (AbstractRequestMonitor+) || within(RequestContext+);
public pointcut voidReturnAdviceExecution() :
adviceexecution() &&
if(((AdviceSignature) thisJoinPointStaticPart.getSignature()).
getReturnType () == void.class);
protected pointcut monitorHelperExec() :
inMonitor() && execution(* *(..)) &&
! execution(* execute(..)) && !execution(* doExecute (..));
protected pointcut monitorExecuteCall() :
(inMonitor() && withincode(* execute(..)) ||
withincode(* doExecute(..))) &&
(call(* *(..)) && !call(* doExecute(..)) || call(new(..)));
public pointcut handlingScope() :
scope() &&
voidReturnAdviceExecution() || monitorHelperExec() || monitorExecuteCall();
/**
* This advice ensures that errors in the monitoring code will not
* poison the underlying application code.
*/
Object around() : handlingScope() {
try {
return proceed();
} catch (Throwable e) {
handleError(e, thisJoinPointStaticPart);
return null;
}
}
public synchronized void handleError(Throwable t,
StaticPart joinPointStaticPart) {
// log 1 in 1000 but don''t rethrow
...
}
/**
* Count of errors: a weak map so we don''t leak memory after apps
* have been disposed of.
*/
private Map/* <JoinPoint.StaticPart, MutableInteger> */errorCount =
new WeakHashMap();
...
}
AOP@Work: 用AspectJ进行性能监视,第2部分(12)
时间:2011-09-07 IBM Ron Bodkin
关于错误隔离层
从清单 10 中可以看到我首先定义了范围的切点,以限定 ErrorHandling 中 的建议只应用于 Glassbox Inspector 中的代码,而不应用到 ErrorHandling 方面本身。然后,我定义了 inMonitor() 切点以定义词句上处于请求监视器中 的代码(包括所 |