JAVA 面向切面编程——运行时切面编织和类加载时切面编织 [英] JAVA Aspect Oriented Programming- Runtime Aspect Weaving and Class Loading time aspect weaving

查看:40
本文介绍了JAVA 面向切面编程——运行时切面编织和类加载时切面编织的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了一篇关于 AOP 的文章,里面提到 Aspect 编织可能发生在编译时、类加载时和运行时.

I came cross a article about AOP, there it is mentioned that Aspect weaving can happen during the compile time, class loading time and during runtime.

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

In java, I could imagine, rather understand, how aspect weaving would actually happens during compile time. Proxy class are generated during class compilation itself(with aspect enabled on project). Generated bytecode would have proxy code.

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

But I am still wondering what exactly (actually) happen, during class loading time weaving and runtime weaving. Does the proxy class gets generated while loading the class? Does aspect library add any programmatic instruction in .class (while compiling) file for proxy class generation?

推荐答案

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

Spring AOP actually uses Java Dynamic Proxies for interfaces and, if necessary, cglib for non-interface types. It only works for Spring Beans. Proxies are generated automatically for all methods matched by a so-called pointcut. This is done during wiring.

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

AspectJ however does not need or even use proxies, it directly generates byte code which is woven into the existing byte code. AspectJ is much more powerful and can do more than just method interception.

  • 对于编译时编织 (CTW),这是由 AspectJ 编译器 ajc 完成的.除了原生 AspectJ 语法(它是 Java 的超集)之外,您还可以使用 Java 注释风格的方式来定义方面,通常称为 @AspectJ 语法.在这种情况下,您可以使用 javac 编译方面,并在单独的构建步骤中使用方面编织器.结果基本相同.在这两种情况下,在运行时您都需要一个小的 AspectJ 运行时库,以便方面按预期工作.
  • CTW 和 LTW(加载时编织)之间的区别在于编织步骤被推迟到类加载时间.为了完成这项工作,您需要在 JVM 命令行上使用一个名为 AspectJ weaver 的 Java 代理库.Java 代理在加载普通应用程序类之前启动,因此可以影响类加载并根据需要检测加载的字节码.分析工具或类似工具也使用此方法.
  • 很明显,LTW 不适用于源代码而是类文件,即 AspectJ 可以将其方面代码编织到任何常规 Java 类文件中.这也可以在运行时之前完成,即您可以将方面代码编织到您没有源代码的外部库中,创建一个新的修改版本,以便在每次加载库时为 LTW 节省时间.这通常称为二进制编织.有了一些额外的知识,甚至可以将方面代码编织到 JDK 中,即通过创建一个包含方面代码的修改过的 rt.jar.但这不是您通常会做的事情,我只是想提一下这是可能的.
  • For compile-time weaving (CTW) this is done by the AspectJ compiler ajc. Instead of native AspectJ syntax (which is a superset of Java) you can also use a Java annotation style way of defining aspects, often called the @AspectJ syntax. In this case you can compile the aspects with javac and use the aspect weaver in a separate build step. The result is basically the same. In both cases, during runtime you need a small AspectJ runtime library in order for the aspects to work as expected.
  • The difference between CTW and LTW (load-time weaving) is that the weaving step is deferred until classloading time. In order to make this work you need a Java agent library, called the AspectJ weaver, on the JVM command line. Java agents are started before normal application classes are loaded and can thus influence classloading and instrument the loaded byte code as desired. This approach is also used by profiling tools or similar.
  • So obviously LTW does not work with source code but class files, i.e. AspectJ can weave its aspect code into any regular Java class file. This can also be done before runtime, i.e. you can weave aspect code into an external library for which you do not have the source code, creating a new, modified version of it in order to save the time for LTW every time the library is loaded. This often is called binary weaving. With some extra knowledge it is even possible to weave aspect code into the JDK, i.e. by creating a modified rt.jar including aspect code. But this is nothing you normally do, I just wanted to mention that it is possible.

这篇关于JAVA 面向切面编程——运行时切面编织和类加载时切面编织的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆