Java Spring引导-编译时编织和Spring AOP/运行时编织(代理)在同一个项目中

Java Spring引导-编译时编织和Spring AOP/运行时编织(代理)在同一个项目中,java,spring,aop,aspectj,spring-aop,Java,Spring,Aop,Aspectj,Spring Aop,如果在同一个项目中有代码同时使用SpringAOP和运行时编织/代理使用以及编译时编织,SpringBoot会做什么。例如,假设您有如下方面: @方面 @组成部分 公共类测试spect{ // ... } 其中@Component的存在意味着我们正在使用SpringAOP和代理,而您的pom.xml中就有这一点 org.codehaus.mojo aspectj maven插件 1.11 编撰 测试编译 这意味着我们正在使用编译时编织 哪个优先?是使用编译时编织还是代理?Hm,为什么不试试

如果在同一个项目中有代码同时使用SpringAOP和运行时编织/代理使用以及编译时编织,SpringBoot会做什么。例如,假设您有如下方面:

@方面
@组成部分
公共类测试spect{
// ...
}
其中@Component的存在意味着我们正在使用SpringAOP和代理,而您的pom.xml中就有这一点


org.codehaus.mojo
aspectj maven插件
1.11
编撰
测试编译
这意味着我们正在使用编译时编织


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

Hm,为什么不试试呢?这不比问问题快吗?好的,以下是我的想法:

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

一句话:您不能混合使用SpringAOP和AspectJLTW,但您应该能够使用SpringAOP+AspectJCTW。你应该有充分的理由这样做,并理解你在做什么。

谢谢你的回复,这很有意义。看起来,即使我的pom中有这些编译时依赖项,但是仍然使用@Component注释我的方面,Spring将使用它自己的Spring AOP并创建代理并使用它们。使用两者的唯一方法是将我想要在编译时处理的那些放在不同的模块中。请让我知道你最后是如何做到的。理论上有几种方法,知道你选择哪一种会很有趣。实际上,没有必要制作原生方面的组件,因为它们不依赖Spring代理或其他Spring机制来完成它们的工作。只有当您出于其他原因想将它们连接到Spring中时,例如,您需要将一些Spring依赖项连接到aspect中,您才会这样做。