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
评论