- Field access
- Exceptions
- Code injection
- Before, After and Around constructs
- Intercepting and completely replacing method calls
I compiled the test classes and the aspects into separate jar files and used the compile time weaver to create a woven jar file separately. My intention was to examine the java bytecode before and after being woven to get a better understanding of aspectj code generation. Knowing what happens under the hood helps in creating better designs. Let me take you through what I went through. I have included the javap outputs and compiled classes along with the source code, but you may want to download the source code and compile them once yourself before we start.
Examining the Aspects Themselves
First, lets examine the aspect bytecode. We pick up one of the simplest aspects - the FieldAccess aspect, and do a bytecode disassembling with javap. Here's what we see:
- It is a public class
(public class ajtest.aspects.FieldAccess extends java.lang.Object) - There is a singleton instance of the aspect stored as ajc$perSingletonInstance and initialized in a static block. So only one instance of the aspect is created when the aspect class loads.
This is an important learning which the novice tend to overlook. This implies that the aspects must be coded to be thread safe. Otherwise, remember to modify the aspect declaration with a per... (perthis, pertarget, ...) modifier. - In case there is an exception during initialization of the aspect, there is a private static Throwable named ajc$initFailureCause declared in the class which is initialized in the static block of the class with the exception.
- Since the aspect was used 'around' the pointcut, there is a method for around and a corresponding method for proceed which is called from within the around method.
public int ajc$around$ajtest_aspects_FieldAccess$1$32f71218(org.aspectj.runtime.internal.AroundClosure);
static int ajc$around$ajtest_aspects_FieldAccess$1$32f71218proceed(org.aspectj.runtime.internal.AroundClosure) throws java.lang.Throwable; - The proceed method is static and does not simply access the field. Instead, it calls run method of the AroundClosure object. That is to futher chain any other aspects that may need to be run.
invokevirtual #67; //Method org/aspectj/runtime/internal/AroundClosure.run:([Ljava/lang/Object;)Ljava/lang/Object; - Note the strange naming convention of the methods, ending with $1$32f71218. We will take it up later and cover another interesting fact of the AspectJ weaver.
- Then there are other generated methods like aspectOf and hasAspect.
- For each injected field, the aspect has initializer, getter and setter methods
public static void ajc$interFieldInit$ajtest_aspects_AroundAndInject$ajtest_java_Test$nCalls(ajtest.java.Test);
public static int ajc$interFieldGetDispatch$ajtest_aspects_AroundAndInject$ajtest_java_Test$nCalls(ajtest.java.Test);
public static void ajc$interFieldSetDispatch$ajtest_aspects_AroundAndInject$ajtest_java_Test$nCalls(ajtest.java.Test, int); - For each injected method, the aspect has the code that goes into the method body. What is injected into the class are methods that in turn call these methods in the aspect.
public static void ajc$interMethod$ajtest_aspects_AroundAndInject$ajtest_java_Test$incCalls(ajtest.java.Test);
public static int ajc$interMethod$ajtest_aspects_AroundAndInject$ajtest_java_Test$getCalls(ajtest.java.Test); - For each injected method, there are local dispatcher methods in the aspect that in turn call the method of the instrumented class.
public static int ajc$interMethodDispatch1$ajtest_aspects_AroundAndInject$ajtest_java_Test$getCalls(ajtest.java.Test);
public static void ajc$interMethodDispatch1$ajtest_aspects_AroundAndInject$ajtest_java_Test$incCalls(ajtest.java.Test); - The aspect itself used the local dispatch methods to access the injected methods or variables. So calling an injected method from within the aspect goes through the following path:
dispatcher method in aspect --> injected method in class --> method body in aspect.
In the next post we'll go through a few woven classes and see what interesting things we can see there.
No comments:
Post a Comment