Ramnivas Laddad 谈 AOP 选型

阅读数:329 2009 年 1 月 11 日

话题:架构

Spring AOP/AspectJ 搭配能提供多种选择,比如 AOP 系统的选择(基于字节码的 AOP 或基于代理的 AOP)、语法的选择(传统的AspectJ、@AspectJ 或 XML 语法),还有织入方式的选择(构建时织入器或加载时织入器);在企业应用中使用 AOP 时,清楚地理解这些选择对实施的效果来说是非常重要的。

Ramnivas Laddad说,只有一种 AOP 是不能适用于所有应用的,选择正确的组合有助于开发人员成功使用 AOP。他在近期的 SpringOne Americas大会上做了演讲,谈论了各种 AOP 设计、Spring AOP 框架提供的实现选择,还有 Web 应用中使用 AOP 的最佳实践。

Ramnivas 讨论了 AspectJ 织入和基于代理的 Spring AOP 方法的优势与不足。在 Spring AOP 和 AspectJ 之间进行选择取决于设计和环境因素。在下述情况下使用 Spring AOP:

  • 单纯的方法拦截就足够了。
  • 全套的 AOP 功能显得太多。
  • 不想使用特殊的编译器,比如 AspectJ 编译器(ajc)。
  • 不需要横切领域对象。
  • 预先提供的方面已经能满足需求。

其它情况使用 AspectJ AOP。他列举了一些 AspectJ(细粒度跟踪和监控,领域对象,细粒度安全)和代理 AOP(事务管理,JMX 监控,远程访问和安全)的例子应用。在演讲过程中,Ramnivas 用代码示例展示了传统 AspectJ@AspectJ语法这两种选择之间的差异。

方面织入选型包含编译时织入和加载时织入(LTW)。使用 LTW 时,你可以使用允许方面织入的 Spring 驱动 LTW,该 LTW 不用修改任何容器启动脚本(没有-javaagent参数),也无需利用 Spring 使用配置选项的 JPA 代理。这两种织入选择之间的比较如下:

构建时织入(编译 / 二进制):

  • 织入在构建时花费时间,但在加载时是全速的。
  • 需要修改构建系统。
  • 无须任何部署修改。
  • 最好的 IDE 支持——Eclipse AspectJ Development Tools(AJDT)。

加载时织入:

  • 加载时速度和内存占用会受到影响。
  • 不用改变构建系统,但为了织入方面,需要修改部署。
  • 没有 IDE 工具的支持。

AOP 设计选择包括利用连接点签名(join point signatures)的切入点实现和使用通配符选择大范围的连接点。元数据(注解)也可用来捕获连接点,该方法有如下优势和不足:

  • 优势:

    用注解捕获应用中特定的横切关注点是一种很简单的方式。注解有助于把方面和类之间的协作只限定于注解。
  • 不足:

    必须需要类的协作。另外,过度利用注解可能会掩盖 AOP 的遗忘性(obliviousness)。

AOP 实现使用元数据的最佳实践有:

  • 注解是表达程序元素固有特性的最佳选择。
  • 注解应该描述清楚连接点上什么是符合要求的,而不是在这些点上应该发生什么。
  • 避免特定实现的注解。
  • 注解应该描述被注解元素的状态。举例来说,为了捕获一个只读场景,用 @ReadOnly 作为注解名,而不要用 @TakeReadLock。要标记一个需要具有事务性的方法,使用 @Transactional,而不要用 @JTATransactional。
  • 不要用注解创建宏。
  • 使用已有的注解,诸如 JPA(@Entity@Table)、JAX-WS(@WebService@WebMethod)、Spring(@Component@Service@Autowired@ManagedResource)。

查看英文原文:Ramnivas Laddad on Making AOP Choices With AspectJ and Spring AOP