JAVA Aspect Oriented Programming- Runtime Aspect Weaving and Class Loading time aspect weaving

落爺英雄遲暮 提交于 2019-12-03 21:02:58

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 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.

  • 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.

Not necessarily at compile time. In Java, through reflection and classloader, you can see and even or modify create methods and classes at runtime, programmatically.

For example, "hello".getClass().getMethod("substring", Integer.TYPE).invoke("my sharona", 3) Will return "sharona", extracting the method substring from a String instance and applying it to another object.

Using a custom classloader, you can define how your class is loaded from the system. This way you can define a method which will called to load (or generate!) the bytecode for a class. You can also use the system classloader to load the bytecode of a class and inspect it.

This technique is widely used by Mozilla Rhino, which can use it to load a compiled JavaScript as a Java bytecode for greater efficiency, or JavAssist, which allows you to create classes, methods, fields and anything at runtime.

Also application servers like JBoss or TomCat use reflection to inspect and manipulate the code, especially through annotations.

Not sure what run-time weaving is. In load-time weaving the agent intercepts the class loading and modifies the byte-code before passing it on to the class loader.

To see how this works is quite easy, for example using AspectJ. You could use compile time weaving and disassemble the code to see exactly how it works. AspectJ can also be instructed to save on disk the generated classes during load time weaving.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!