【问题标题】:Spring Boot - Compile time weaving and Spring AOP/run time weaving (proxies) in same projectSpring Boot - 同一项目中的编译时编织和 Spring AOP/运行时编织(代理)
【发布时间】:2021-05-04 10:54:33
【问题描述】:

如果有代码在同一个项目中同时使用带有运行时编织/使用代理的 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>

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

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

【问题讨论】:

    标签: java spring aop aspectj spring-aop


    【解决方案1】:

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

    • 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 切面放入另一个模块、创建切面库,然后通过 &lt;aspectLibraries&gt; 配置在 AspectJ Maven 中引用它来实现这一点。

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

    【讨论】:

    • 感谢您的回复,这是有道理的。似乎即使我的 pom 中有那些编译时依赖项,但是仍然用 @Component 注释我的方面,Spring 将使用它自己的 Spring AOP 并创建代理并使用它们。使用两者的唯一方法是将我想要在编译时处理的那些放在不同的模块中。
    • 请告诉我你最后是怎么做到的。理论上有几种方法,知道你选择了哪一种会很有趣。实际上,确实没有必要制作原生方面@Components,因为它们不依赖 Spring 代理或其他 Spring 机器来完成它们的工作。仅当您出于其他原因想以某种方式将它们连接到 Spring 时,例如您需要将一些 Spring 依赖项连接到方面,您会这样做吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-18
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多