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

查看:76
本文介绍了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 Dynamic Proxies用于接口,如有必要,将 cglib 用于非接口类型.它仅适用于Spring Beans.对于由切入点匹配的所有方法,将自动生成代理.这是在接线过程中完成的.

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 编译方面,并在单独的构建步骤中使用方面weaver.结果基本相同.在这两种情况下,在运行时期间,都需要一个小的AspectJ运行时库,以便各方面按预期工作.
  • CTW和LTW(加载时编织)之间的区别在于,编织步骤被延迟到类加载时间之前.为了使此工作有效,您需要在JVM命令行上有一个Java代理库,称为AspectJ weaver. 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天全站免登陆