微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Spring Boot - 编译时编织和 Spring AOP/运行时编织代理在同一项目中

如何解决Spring Boot - 编译时编织和 Spring AOP/运行时编织代理在同一项目中

如果有代码在同一项目中使用带有运行时编织/使用代理和编译时编织的 Spring AOP,Spring Boot 会做什么。例如,假设您有一个如下所示的方面:

@Aspect
@Component
public class TestAspect {
  // ...
}

@Component 的存在意味着我们正在使用 Spring AOP 和代理,而你的 pom.xml 中有这个

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>aspectj-maven-plugin</artifactId>
  <version>1.11</version>
  <executions>
    <execution>
      <goals>
        <goal>compile</goal>       <!-- use this goal to weave all your main classes -->
        <goal>test-compile</goal>  <!-- use this goal to weave all your test classes -->
      </goals>
    </execution>
  </executions>
</plugin>

这意味着我们正在使用编译时编织。

哪个优先?是使用编译时编织,还是使用代理?

解决方法

嗯,你为什么不试试呢?这不会比问快吗?好的,这是我的想法:

  • AspectJ 完全独立于 Spring AOP 或 Spring。您可以在没有 Spring 的情况下使用它,也可以在 Spring 应用程序中使用它,通常是通过加载时编织 (LTW)。 Spring 手册解释了如何配置它。
  • 如果您使用 LTW,Spring 会知道它,要么是因为您通过 Spring 选项显式配置它,要么仅仅是因为 Spring 以某种方式检测到活动编织代理。无论哪种方式,只要 LTW 处于活动状态,Spring 就会停用它自己的 Spring AOP。
  • 关于编译时编织 (CTW),Spring 不知道它,因为它发生在构建时,甚至在 Spring 启动之前。根据您使用的 AspectJ 功能类型,AspectJ 增强类可能看起来与常规 Java 类没有什么不同,例如用于简单的 ITD 字段或方法定义。然而,在大多数情况下,这些修改使得您需要类路径上的 AspectJ 运行时库 aspectjrt.jar。如果是这种情况,无论有没有 Spring,应用程序都应该正常运行。
  • 在 Spring 的情况下,我不希望它首先注意到您之前使用过 CTW 的任何信息。因此,它不会停用 Spring AOP。您应该能够将两者结合使用。只要确保不要将您的原生方面声明为 Spring 组件,否则 Spring AOP 会尝试重新应用它。结果将是不可预测的。但是普通的 Spring AOP 方面组件应该可以正常工作。当然,您还需要确保 AspectJ Maven 不会意外地将您的 Spring AOP 方面编译和编织为原生方面。您可以通过将 AspectJ 切面放入另一个模块、创建切面库,然后通过 <aspectLibraries> 配置在 AspectJ Maven 中引用它来实现这一点。

底线:您不能混合使用 Spring AOP 和 AspectJ LTW,但您应该可以使用 Spring AOP + AspectJ CTW。您应该有充分的理由这样做并了解您在做什么。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。