如何使用 AspectJ weaver 自定义注释制作 Spring

How to make Spring with AspectJ weaver custom annotations

在我们的项目中,我们正尝试从 Spring 标准 AOP 转移到 AspectJ,如 this 等许多地方所解释的那样(我们需要使一些私有和受保护的方法具有事务性)。

我们已经能够使用标准 Spring 注释(如 @Transactional)使这项工作正常进行。但是我们面临的问题是在我们的项目中有一些 AspectJ 无法识别的自定义 Annotations(不是自定义方面)。例如,我们有这样的注释 'extends' @Transactional (只修改 rollbackFor 属性):

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.CLASS)
@Transactional(rollbackFor = Exception.class)
public @interface TransactionalWithCheckedException {

}

关于如何告诉 AspectJ 编织器还有这个自定义注释的想法吗?可能吗?如果不是,我是否应该构建扩展 Spring 的自定义方面(即:对于 @Transactional)。

有关更多信息,这是 aop.xml:

<aspectj>
  <aspects>
    <!-- Aparently no need to explicit declare aspects like the ones used by Spring @Transactional or @Async, they work fine. -->
  </aspects>
<weaver options="-XnoInline -Xreweavable -showWeaveInfo">
  <include within="com.mycompany.myproject..*" />
</weaver>

以及 Spring 的上下文配置文件的一部分:

 <tx:annotation-driven mode="aspectj" />
 <context:load-time-weaver />

嗯,首先,Spring @Transactional注解不是元注解,所以不能用在注解类型上。此外,spring 事务代码中的任何内容都不支持这种用法。为了支持这种用法,您必须创建一个具有适当切入点的专门方面来识别事务边界处的连接点,可能同时支持原始 Spring @Transactional 注释和您的自定义注释也是如此。您还需要为方面提供 TransactionAttributeSource 的实现以支持您自己的元数据源,在您的情况下,该接口的实现处理 @TransactionalWithCheckedException 注释(您的兴趣点将是 TransactionAttribute.rollbackOn(Throwable ex) 方法)。然后,您可以使用 CompositeTransactionAttributeSource 作为 TransactionAttributeSource 的实现,这样您就可以将支持 Spring 的 @Transactional 注释的元数据源与您的注释结合起来。

总而言之,您需要这两件事来处理特殊的交易属性:

  • 支持您和 Spring 注释的具体方面(可能是 AbstractTransactionAspect 的子类,请参阅 AnnotationTransactionAspect 了解实现思路`
  • a TransactionAttributeSource 实现处理您的事务注释。使用 CompositeTransactionAttributeSource 将元数据支持与 spring 的元数据 (AnnotationTransactionAttributeSource) 相结合。