题外话:用StaticJoinPoint来最优化
AspectWerkz 2.0支持StaticJoinPoint的概念,与普通的JoinPoint不同的是,StaticJoinPoint不提供对运行时类型信息(Runtime Type Information,RTTI)的访问。通过除去RTTI,编写者能优化对方面的调用,因为不再需要为JoinPoint收集动态数据并使其保持有效。
例如,前一节中的日志记录方面记录了每个方法调用的参数值,因此需要访问RTTI。如果不想记录参数,可以使用StaticJoinPoint来提高性能。下面的方面代码和定义正是这么做的:
public class LoggingIdiom {
public Object trace(StaticJoinPoint jp,
Loggable loggable)
throws Throwable {
CodeSignature cs =
(CodeSignature) jp.getSignature();
loggable.getLog().enter(
methodSignature(cs));
Object result = jp.proceed();
loggable.getLog().exit(
exitTrace(jp, result));
return result;
}
}
...
<aspect class="com.tss.aop.LoggingIdiom">
<pointcut name="p2"
expression="execution(* com.tss..*.*(..))
AND avoidTrace" />
<advice name="trace(StaticJoinPoint jp,
com.tss.aop.Loggable loggable)"
type="around"
bind-to="p2 AND target(loggable)" />
</aspect>
实现性能剖析方面
实现性能剖析方面要比实现日志记录方面容易得多,因为剖析器可以静态调用。这使我们可以定义下面的简单方面,而不需要mixin:
public Object profile(StaticJoinPoint jp)
throws Throwable {
Profiler.push(methodSig(jp));
Object result = jp.proceed();
Profiler.pop(methodSig(jp));
return result;
}
这段代码非常简单明了。但是,aop.xml中的方面定义更有趣。我们只是想剖析那些特定于web请求的切入点,所以选择切入点时使用cflow表达式。
<aspect class="com.tss.aop.ProfilingIdiom">
<pointcut name="p3" expression="cflow(
execution(* com.tss.blog.web.
ApplicationServlet.service(..)))
AND execution(* com.tss..*(..))
AND avoidTrace"/>
<advice name="profile(StaticJoinPoint jp)"
type="around" bind-to="p3"/>
</aspect>
cflow表达式允许我们只选择Tapestry页的控制流中的那些切入点。换句话说,每个在web请求的执行中进行的调用都会被剖析。这是一个非常强大的表达式,它允许我们解决避免剖析初始化代码的问题。我们可以只剖析那些感兴趣的代码。实际上,我们可以定义多个剖析器实例,它们基于剖析的内容有不同的行为。例如,花费多于5秒的web请求可能触发一个错误,而任何预定的后台任务花费超过10秒钟也可能产生一个错误。
结束语
我们已经看到,把AOP应用于示例应用程序使代码基要易于编写得多,同样,灵活性和一致性也更好。通过使用独立的方面来实现日志记录关注点和性能剖析关注点,我们解决了原始应用程序中凸现的所有问题。开发人员不再需要把这些关注点直接结合到代码中。阅读完本文并浏览完随文所附的源代码后,用不到一天的时间就可以把这些方面结合到您的代码基中去。如果您的项目早点这么做,您就会意识到节省了很多成本,而您团队中的开发人员会非常感激您。
重要的是,在使用AOP的过程中要注重实效,非必要不用,尤其是在已经存在一个同等好的非AOP方案时。据说,如果某人故意太长时间不用方面考虑问题,像把剖析器和记录器结合起来这样的实现hack也开始似乎正常了。当代码只是因为您对在所有的类中输入相同的代码感到厌倦而开始变得紧密联系时, AOP能够真正帮助您简化代码基。
即将出现的Aspect 5版本将支持本文用到的所有功能。这里所描述的一切都将自然迁移到Aspect 5中。首次发布可能在今年晚些时间。
