JAVA 面向方面编程 - 运行时方面编织和类加载时方面编织

2023-12-31

我看到一篇关于 AOP 的文章,其中提到切面编织可以在编译时、类加载时和运行时发生。

在java中,我可以想象,甚至可以理解,方面编织在编译时实际上是如何发生的。代理类是在类编译期间生成的(在项目上启用了方面)。生成的字节码将具有代理代码。

但我仍然想知道在类加载时编织和运行时编织期间到底发生了什么。加载类时是否生成代理类?方面库是否在 .class(编译时)文件中添加任何编程指令以生成代理类?


春季AOP实际上,接口使用 Java 动态代理,并且如有必要,cglib对于非接口类型。它仅适用于 Spring Bean。代理是为所有与所谓的切入点匹配的方法自动生成的。这是在接线期间完成的。

AspectJ然而不需要甚至不需要使用代理,它直接生成字节码并编织到现有的字节码中。 AspectJ 更强大,不仅仅可以做方法拦截。

  • 对于编译时编织 (CTW),这是由 AspectJ 编译器完成的ajc。除了本机 AspectJ 语法(它是 Java 的超集)之外,您还可以使用 Java 注释样式的方式来定义切面,通常称为 @AspectJ 语法。在这种情况下,您可以使用以下方式编译方面javac并在单独的构建步骤中使用切面编织器。结果基本是一样的。在这两种情况下,在运行时,您都需要一个小的 AspectJ 运行时库,以便各方面按预期工作。
  • CTW 和 LTW(加载时编织)之间的区别在于编织步骤被推迟到类加载时间。为了完成这项工作,您需要一个位于 JVM 命令行上的 Java 代理库,称为 AspectJ weaver。 Java 代理在加载正常应用程序类之前启动,因此可以影响类加载并根据需要检测加载的字节代码。这种方法也被分析工具或类似工具使用。
  • 显然,LTW 不适用于源代码,而是使用类文件,即 AspectJ 可以将其方面代码编织到任何常规 Java 类文件中。这也可以在运行时之前完成,即您可以将方面代码编织到您没有源代码的外部库中,创建一个新的修改版本,以便在每次加载库时节省 LTW 的时间。这通常称为二元编织。有了一些额外的知识,甚至可以将方面代码编织到 JDK 中,即通过创建修改后的rt.jar包括方面代码。但这不是你通常会做的事情,我只是想说这是可能的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA 面向方面编程 - 运行时方面编织和类加载时方面编织 的相关文章

随机推荐