gpt4 book ai didi

architecture - 运行时 AOP 与编译时 AOP

转载 作者:行者123 更新时间:2023-12-03 06:14:31 30 4
gpt4 key购买 nike

这两种AOP框架的优缺点是什么?我使用 Unity 作为我的 aop 框架,但我猜想编译时 aop 框架(例如 postsharp)可能比运行时 aop 框架具有更好的性能?看起来运行时 aop 框架使用反射来实现注入(inject)。

最佳答案

我不是 .NET 人,但我了解 Java 生态系统中的 AOP 世界,尤其是 AspectJ 和 Spring AOP。基本上有 4 种类型的方面编织:

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

  • 通常,良好的方面编译器(例如 AspectJ)创建非常高效的字节码,并且在运行时不太依赖反射。如果您选择的方面框架确实依赖于反射,那么它可能不是很快。但也许它足够快,这取决于您使用方面的程度。

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

    关于architecture - 运行时 AOP 与编译时 AOP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39448543/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com