【问题标题】:Aspect weaving at runtime在运行时编织方面
【发布时间】:2013-06-23 19:04:18
【问题描述】:

我正在寻找一种 Java 解决方案,它允许我在运行时使用 AOP 在已经运行的代码之上编织新代码。关键是不需要重启JVM。另外,我想在运行时删除编织,让旧代码以编织前的方式运行。

我认为 AspectJ 加载时间编织 + 运行时类加载/卸载可以做到这一点。有人试过吗?有什么建议吗? 谢谢。

【问题讨论】:

  • 我知道这是旧的,但仍列为未答复。如果它看起来合适,请您接受并支持我的回答吗?谢谢。

标签: java runtime aop aspectj load-time-weaving


【解决方案1】:

需要考虑的几点:

  • 确实,您可以类加载期间进行LTW,但不能类已经加载之后。
  • 没有类卸载这样的概念,因为要卸载一个类,它需要进行垃圾回收,并且不能再存在对该类的引用。即使是后者,JVM 规范 AFAIK 也将其声明为可选的,是否以及何时卸载或 GC 应清除已加载的类。你永远不能依赖它。

话虽如此,您可以尝试诸如 OSGi 之类的概念,也可以编写自己的类加载器(或在 Internet 上找到许多现有的类加载器),将每个类或每个 JAR 加载到单独的类加载器实例中。这可能会变得非常复杂,所以也许您想考虑这种简单的方法,只要它在您的情况的技术范围内:

  • 将方面编译到代码中或使用 LTW,这并不重要。只需确保在实际使用类之前编织方面代码。编译时间显然绰绰有余,加载时间刚刚够快,但还好。
  • 对所有相关建议使用if() pointcuts,并提供一种动态更改切入点使用的变量值的方法,以便能够动态打开和关闭建议。性能开销通常很小,不用担心。在你说它太贵之前先试一试。

此解决方案满足您的条件,即它可以动态(停用)激活,并且在编织切面代码后无需重新启动 JVM。

【讨论】:

  • 嗯,这让开发人员有责任编写可以打开/关闭的方面。我想避免它。
  • 我正在考虑使用 JRebel 或任何其他运行时类重新加载工具。由于类在运行时重新加载,我的假设是它也允许在重新加载时重新编织。
  • 嗯,我认为开发人员确实有责任。核心代码开发人员负责核心代码,方面开发人员负责横切关注点。所以我想这不是要求太多。不管怎样,只是因为你让我好奇,我上周末快速尝试了 JRebel,并将它与 AspectJ 一起使用。它在编译时编织时工作得很好,但我无法在加载时编织的 5 分钟内(这并不意味着太多)让它工作。它对开发人员来说是一个不错的工具,但我不确定我是否会在生产中使用它。
【解决方案2】:

方面

方面是您正在实现的横切功能。这是您正在模块化的应用程序的方面或区域。方面最常见(尽管很简单)的示例是日志记录。日志记录是整个应用程序所必需的。但是,由于应用程序倾向于根据功能分解为层,因此通过继承重用日志记录模块

没有意义。但是,您可以创建一个日志记录方面并使用 AOP 在整个应用程序中应用它。


编织

编织是将方面应用到目标对象以创建新的代理对象的过程。方面在指定的连接点处被编织到目标对象中。编织可以在目标类的生命周期中的多个时间点进行:

  • 编译时间:编译目标类时会编织方面。这需要一个特殊的编译器。
  • 类加载时间:当目标类加载到 JVM 中时,方面会被编织。这需要一个特殊的 ClassLoader 在引入类之前增强目标类的字节码 进入应用程序。
  • 运行时:方面是在应用程序执行期间的某个时间编织的。通常,AOP 容器会动态地 生成一个代理类,该代理类将委托给目标类,同时 编织方面。


(Source)

【讨论】:

  • 这实际上并没有解决问题。这只是关于 AOP 的一般信息。
  • 编织是将方面应用到目标对象以创建新的代理对象的过程 --- 只有在 SpringAOP 范围内“创建新的代理目标”时才适用,不适用于 Aspectj。
【解决方案3】:

您可以实施一个 ASM 解决方案,允许在运行时在已经运行的代码之上编织新代码(无需停机)

  • ASM 可以重新转换已经加载的类,它基本上读取文件上的类并重新转换内存中加载的类
  • 使用 ASM 进行操作 (https://www.baeldung.com/java-asm)

您可以使用相同的解决方案在运行时移除编织物

  • 加载的类保留在文件系统上,可以重新加载。

【讨论】:

  • 任何关于使用 Aspectj 进行此操作的教程?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2018-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
相关资源
最近更新 更多