方面在运行时编织

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

我在想AspectJ加载时编织+运行时类加载/卸载会做到这一点。 有人试过吗? 有什么建议? 谢谢。

需要考虑的一些事项:

  • 没错,您可以类加载期间执行LTW,但不能已经加载类之后执行LTW。
  • 没有像类卸载这样的概念,因为要卸载的类需要进行垃圾收集,因此不再存在对类的引用。 即使后者是这种情况,JVM规范AFAIK也会将其声明为可选,无论是否卸载或GC应该清除已经加载的类。 你永远不能依赖它。

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

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

此解决方案满足您的条件,即可以(de)动态激活,并且在编制方面代码后不需要重新启动JVM。

方面

一个方面是您正在实施的跨领域function。 它是您正在模块化的应用程序的方面或区域。 一个方面最常见的(尽管很简单)示例是日志记录。 记录是整个应用程序所需的。 但是,由于应用程序倾向于根据function分解为多个层,因此通过inheritance重用日志记录模块

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


织造

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

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

在此处输入图像描述
在此处输入图像描述

(资源)