运行时 AOP 与编译时 AOP

2024-01-18

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


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

  • Source code weaving: Aspect code is injected as source code statements into your application source code. This is some kind of preprocessor approach. No AOP framework in the Java world uses this approach nowadays, but there used to be some in the early days of AOP.
    • 如果做得正确的话,优点是在运行时完全独立于任何运行时库或特殊的 AOP 编译器。
    • 缺点是源代码臃肿,并且编译前需要预处理/代码生成步骤。您始终需要生成的源代码进行调试。
  • Compile-time weaving: Aspect code is woven into your application by a special compiler.
    • 优点是方面编织没有运行时开销。您唯一需要的是类路径上的一个小型运行时库。
    • 缺点是,如果您想将各个方面编织到应用程序中,则无法将决定推迟到运行时。但这只是在处理并不总是需要的调试或跟踪方面时的问题。另一个缺点是这种方法仅适用于您控制下的代码,即您需要拥有源代码。它不适用于第 3 方库。
  • Binary weaving: Aspect code is woven into existing class files after compilation rather than during compilation.
    • 优点是它也适用于您没有源代码的第三方代码。这种方法也可以与编译时编织混合使用。您还可以避免加载时编织的开销(见下文)。
    • 缺点与编译时编织类似:一旦切面被编织到代码中,您就无法取消应用它,只能通过切入点停用其执行,例如if()。但这可能非常有效。
  • Load-time weaving (LTW): A weaving agent/library is loaded early when your VM/container is started. It gets a configuration file with rules describing which aspects should be woven into which classes.
    • 优点是您可以动态决定是否编织/编织什么。如果通过字节码转换而不是通过动态代理或反射(见下文)完成,则生成的字节码与通过编译时或二进制编织创建的字节码同样有效。另一个优点是,就像二进制编织一样,它适用于您自己的代码以及第三方代码,只要编织代理可以“看到”它,即它发生在子类加载器中。
    • 缺点是应用程序启动期间的一次性编织开销,因为编织是在类加载发生时完成的。
  • Proxy-based LTW: This special LTW form is used by Spring AOP while AspectJ does the previous 3 forms listed above. It works by creating dynamic proxies (i.e. subclasses or interface implementations) for aspect targets.
    • 除了您选择的框架(例如 Spring)碰巧支持它之外,我想不出任何特殊的优势。
    • 缺点是由于基于代理的方法而限制了公共、非静态方法和运行时开销。它也不会捕获内部方法调用,即当代理类调用其自己的方法之一时,因为这些调用不会被代理捕获。不支持特殊类型的切入点,例如构造函数拦截、成员变量读/写访问等等,这使得这更像是一种“AOP lite”方法。但这足以满足您的目的。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行时 AOP 与编译时 AOP 的相关文章

  • n 层架构 - BLL、DAL 和接口。什么是最佳实践?

    我有一个关于 n 层架构的问题 在问这个问题之前 我想了很久 因为这里已经有很多类似的问题了 但是 在看了一天半并阅读了其他答案之后 我仍然不确定 各种看似相似的术语和不同的方法让我感到困惑 如果我在不同的类库中有一个 BLL 和一个 DA
  • ASP.NET MVC 和 Web 服务

    向我的 ASP NET MVC 项目添加 Web 服务是否会破坏 MVC 的整个概念 该 Web 服务 WCF 依赖于我的 MVC 项目中的模型层来与后端进行通信 因此在我看来 它需要成为 MVC 解决方案的一部分 我应该将其添加到控制器层
  • 宏定义确定大端还是小端机?

    是否有一行宏定义来确定机器的字节顺序 我正在使用以下代码 但将其转换为宏会太长 unsigned char test endian void int test var 1 unsigned char test endian unsigned
  • 存储徽章标准的最佳方式?

    我一直在考虑如何在新网站上实现类似于SO的徽章功能 存储徽章标准的最佳方式是什么 两个想法 All code 第二系统 创建一个元架构来定义徽章及其标准 在数据库中存储一些信息 并让代码查询它以找出徽章及其标准 还有更好的方法吗 Rules
  • 如何建立一个类似Jira的SaaS网站?

    任何人都知道如何构建单租户 SaaS 应用程序 例如 Jira Wordpress com 等 其中每个客户都有一个单独的站点 但托管在公司服务器上 网络上似乎有很多关于多租户 SaaS 应用程序以及如何在 Heroku Openshift
  • 如何发出 JMS 同步请求

    我有一个 Web 应用程序 预计将从外部应用程序获取和显示数据 该外部应用程序只能通过消息传递 JMS 访问 因此 如果用户在浏览器上提交请求 则同一 HTTP 请求线程将必须与消息系统 MQ 系列 交互 以便同一请求线程可以显示从消息系统
  • 围绕建议并继续调用:aspectJ,它是如何工作的?

    我一直在试图弄清楚是什么around advice工作于AspectJ 这并不像下面这样简单before之后advice 有人可以简要介绍一下around建议确实如此 其目的是什么proceed关键词 非常非正式地 一个around adv
  • 托管扩展性框架 (MEF) 与复合 UI 应用程序块 (CAB)

    我们目前正在考虑在下一个应用程序中使用 CAB 或 MEF 我没有在 Codeplex 上看到任何有关如何处理同级控制通信的事件代理的示例 也许我错过了 MEF 中的控制间通信如何工作 此外 我们计划使用 Infragistics 它为 C
  • 如何以 REST方式发送 HTML 表单?

    我有一个名为 事实 的资源集合的 URI 以及该集合中每个 事实 资源的 URI 我相信 创建新 事实 的表单应该使用 GET 来请求 但我无法确定应该将其设置为哪个 URI 对集合 URI 的 GET 应返回 事实 资源 URI 的列表
  • 在 DDD 中,表示层可以同时使用 Repository 和 Service 类吗?

    如果表示层只应该使用服务 那么服务类必须公开存储库已实现的相同方法 以使它们可供表示层使用 这似乎是错误的 有人可以帮我澄清一下吗 我敢打赌 这似乎是错误的 因为您实际上并不需要这种抽象级别 应用服务有facades http en wik
  • C:epoll和多线程

    我需要创建专门的 HTTP 服务器 为此我计划使用 epoll sycall 但我想利用多个处理器 核心 但我无法提出架构解决方案 ATM我的想法如下 使用自己的epoll描述符创建多个线程 主线程接受连接并将它们分配给线程epoll 但还
  • 如何在无 null 设计中实现 List、Set 和 Map?

    当您在大多数情况下可以返回 null 空对象以避免 null 时 这很好 但是像 Collection 这样的对象呢 在爪哇 Map回报null if key in get key 地图上没有找到 我能想到的最好的避免方法null在这种情况
  • 不支持动态值作为注释中的属性 - AspectJ Android [AOP Android]

    我正在使用自定义注释来记录用户单击的 id 但我收到一个错误 属性值必须是常量 我的代码片段如下 mAssetId Asset getContentId TrackEvent track event ArrayParams Params k
  • 有人有 Postsharp 制作经验吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • List、IList、IEnumerable、IQueryable、ICollection,哪个返回类型最灵活?

    我之前已经在这里看到过这个问题 但我不满意我理解的完整后果 问题是使用 linq to sql 返回的数据层应该使用什么返回类型以获得最大的灵活性和查询能力 这是我读过 发现的 IEnumerable 是有限的 只允许向前读操作 IEnum
  • Ruby 依赖注入库

    我一直在研究一些 Ruby 依赖注入库 特别是 我检查了Needle http needle rubyforge org and Copland http copland rubyforge org 它们已经存在很长一段时间了 但用途并不多
  • 使用 LINQ to SQL 的 .NET 架构的最佳设计实践(DAL 必要吗?我们真的可以使用 POCO吗?要采用的设计模式吗?)

    我避免在 net arch n 层架构上编写看起来像是另一个线程的内容 但请耐心等待 希望我和其他人一样 在选择用于企业应用程序的架构时 考虑到当今的趋势和新兴技术 仍然没有 100 满意或不清楚应采取的最佳方法 我想我正在寻求大众社区对方
  • 为什么 Jersey 控制器未检测到我的方面(使用自定义注释)?

    我想在 Jersey 控制器上创建一个方面来测量服务执行所需的时间 我正在与我的切入点作斗争 因为它没有被检测到 而且我的方面永远不会启动 我尝试过使用很多切入点 例如 execution Monitor execution public
  • 如何使用 AspectJ 将字段添加到自定义注释的类

    要使用aspectj向某个特定类添加字段 我们需要这样做 package com test public class MyClass private String myField public aspect MyAspect private
  • RESTful API:我应该在哪里编码我的工作流程?

    我正在开发一个 RESTful API 这是我的第一个 API 也是我的第一个真正大型的编码项目 因此 我仍在学习很多关于建筑等方面的知识 目前 我的 api 设置分为以下几层 HTTP层 资源层 领域模型 业务逻辑层 数据访问 存储层 持

随机推荐