Architecture 运行时AOP与编译时AOP

Architecture 运行时AOP与编译时AOP,architecture,aop,Architecture,Aop,这两种AOP框架的优缺点是什么?我使用Unity作为我的aop框架,但是我想像postsharp这样的编译时aop框架可能比运行时aop框架有更好的性能?运行时aop框架似乎使用反射来实现注入。我不是.NET的人,但我知道Java生态系统中的aop世界,特别是AspectJ和Spring aop。基本上有4种方面编织: 源代码编织:方面代码作为源代码语句注入到应用程序源代码中。这是某种预处理器方法。现在Java世界中没有一个AOP框架使用这种方法,但在AOP的早期曾经有一些。 这样做的好处是

这两种AOP框架的优缺点是什么?我使用Unity作为我的aop框架,但是我想像postsharp这样的编译时aop框架可能比运行时aop框架有更好的性能?运行时aop框架似乎使用反射来实现注入。

我不是.NET的人,但我知道Java生态系统中的aop世界,特别是AspectJ和Spring aop。基本上有4种方面编织:

  • 源代码编织:方面代码作为源代码语句注入到应用程序源代码中。这是某种预处理器方法。现在Java世界中没有一个AOP框架使用这种方法,但在AOP的早期曾经有一些。
    • 这样做的好处是在运行时完全独立于任何运行时库或特殊的AOP编译器(如果正确的话)
    • 缺点是源代码臃肿,编译前需要进行预处理/代码生成。您总是需要生成的源代码进行调试
  • 编译时编织:方面代码由一个特殊的编译器编织到应用程序中。
    • 优点是方面编织没有运行时开销。您只需要在类路径上有一个小的运行库
    • 缺点是,如果希望在运行时将方面编织到应用程序中,则不能推迟决策。但这只是在处理调试或跟踪并非一直需要的方面时的问题。另一个缺点是这种方法只适用于您控制下的代码,即您需要有源代码。它不适用于第三方LIB
  • 二进制编织:方面代码在编译后而不是在编译期间编织到现有类文件中。
    • 其优点是,它也适用于没有源代码的第三方代码。这种方法也可以与编译时编织混合使用。您还可以避免加载时编织的开销(见下文)
    • 缺点与编译时编织类似:一旦方面被编织到代码中,就不能取消应用它,而只能通过切入点(如
      if()
      )来停用它的执行。但这可能相当有效
  • 加载时编织(LTW):当VM/容器启动时,编织代理/库会提前加载。它获取一个配置文件,其中包含描述哪些方面应编织到哪些类中的规则。
    • 优点是您可以动态地决定是否/编织什么。如果通过字节码转换而不是通过动态代理或反射(见下文)完成,则生成的字节码与通过编译时或二进制编织创建的字节码具有同等的效率。另一个优点是,与二进制编织一样,它适用于您自己的代码以及第三方代码,只要编织代理可以“看到”它,即它发生在子类加载器中
    • 缺点是在应用程序启动期间一次性的编织开销,因为编织是在类加载时完成的
  • 基于代理的LTW:Spring AOP使用这种特殊的LTW表单,而AspectJ使用上面列出的前3种表单。它通过为方面目标创建动态代理(即子类或接口实现)来工作。
    • 除了您选择的框架(比如Spring)恰好支持它之外,我想不出有什么特别的优势
    • 缺点是由于基于代理的方法对公共、非静态方法和运行时开销的限制。它也不捕获内部方法调用,即当代理类调用其自己的方法之一时,因为这些调用不是由代理捕获的。不支持特殊类型的切入点,如构造函数拦截、成员变量读/写访问等,这使得这种方法更像是一种“AOP lite”方法。但它可以满足您的目的
通常,良好的方面编译器(如AspectJ)会创建非常高效的字节码,并且在运行时不会严重依赖反射。如果你选择的方面框架确实依赖于反射,那么它可能不是很快。但也许它足够快,这取决于您使用方面的程度


也许我已经写得太多了,但我可以写得更多。这就是我现在停下来的原因。此外,这类问题不太适合StackOverflow,因为它会导致哲学讨论和基于观点的辩论。尽管如此,我还是希望自己能够做到相当客观/公正。

这是一个令人敬畏的解释。我们不能说aspectJ不使用反射吗?你还说AspectJ做这三件事:编译时,二进制,加载时。我们可以选择使用哪一件,还是在内部进行?阿米尔,你可以通过阅读。我建议尝试使用它,而不是问自己关于它的理论问题。至于第二个问题,作为开发人员,您可以决定要使用哪种类型的编织。如果您没有相应地配置构建环境,AspectJ不会做任何事情。@kriegaex AspectJ编译器比java编译器有任何缺点吗?假设我们使用编译时编织,由于aspectj编译器,我们面临一个问题。在无法修复aspectj编译器的情况下,我们必须进行大量更改以使其重新工作。简而言之,编译时编织似乎是最佳选择,但aspectj编译器似乎是一个破坏者。你对此有什么看法?我的看法是:有些人能为每个问题找到解决办法。其他人在每一个解决方案中都会发现问题。此外,AspectJ编译器是EclipseJava编译器的一个定期更新的分支,并且维护得非常好。与Oracle JVM相比,更容易引起维护人员的注意。我的建议是:也要看到机会,而不是机会