Get Started with AspectJ

  1. Download AspectJ
  2. Run java -jar aspectj-[version].jar and perform the installation.
  3. Add the bin directory of to your path to make it easier to run the AsjpectJ compiler ajc.
  4. Add aspectjrt.jar to your classpath.
  5. The goal of this example is to extend this simple class with logging functionality. Every time a method is called or exited, a message must be logged to stdout.

    Test.java:

    public class Test
    {
       public static void main(String []args) {
          a();
       }
       
       public static void a() {
          b();
       }
       
       public static void b() {
          c();
       }
       
       public static void c() {
          System.out.println("C reached!");
       }
    }
    
  6. Running this code yields:
    C reached!
    
  7. Now write the Logging Aspect.

    TraceAspect.java:

    import org.aspectj.lang.*;
     
    public aspect TraceAspect
    {
       pointcut traceMethods() 
          : (execution(* *.*(..))
            || execution (*.new(..))) && !within(TraceAspect);
             
       before() : traceMethods() {
          Signature signature = thisJoinPointStaticPart.getSignature();
            
          System.out.println("Entering method " + signature.getDeclaringType().getName() + "." +
                                                  signature.getName());
       }
     
       after() : traceMethods() {
          Signature signature = thisJoinPointStaticPart.getSignature();
          
          System.out.println("Exiting method " + signature.getDeclaringType().getName() + "." +
                                                 signature.getName());
       }
    }
    
  8. Compile both the .java files with the ajc:
    ajc *.java
    
  9. Running Test again results in the logging statements.
    Entering method Test.main
    Entering method Test.a
    Entering method Test.b
    Entering method Test.c
    C reached!
    Exiting method Test.c
    Exiting method Test.b
    Exiting method Test.a
    Exiting method Test.main
    
  10. Notice that the original code in Test.java was not touched. But if you decompile Test.class with Jad, you’ll see why Test behaves the way it does, with the logging:
    // Decompiled by Jad v1.5.6d. Copyright 1997-99 Pavel Kouznetsov.
    // Jad home page: http://www.geocities.com/SiliconValley/Bridge/8617/jad.html
    // Decompiler options: packimports(3) 
    // Source File Name:   Test.java
     
    import java.io.PrintStream;
    import org.aspectj.runtime.reflect.Factory;
     
    public class Test
    {
        public Test()
        {
            try
            {
                TraceAspect.aspectOf().ajc$before$TraceAspect$1$b314f86e(ajc$tjp_0);
            }
            catch(Throwable throwable)
            {
                TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_0);
                throw throwable;
            }
            TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_0);
        }
     
        public static void main(String args[])
        {
            try
            {
                TraceAspect.aspectOf().ajc$before$TraceAspect$1$b314f86e(ajc$tjp_1);
                a();
            }
            catch(Throwable throwable)
            {
                TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_1);
                throw throwable;
            }
            TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_1);
        }
     
        public static void a()
        {
            try
            {
                TraceAspect.aspectOf().ajc$before$TraceAspect$1$b314f86e(ajc$tjp_2);
                b();
            }
            catch(Throwable throwable)
            {
                TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_2);
                throw throwable;
            }
            TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_2);
        }
     
        public static void b()
        {
            try
            {
                TraceAspect.aspectOf().ajc$before$TraceAspect$1$b314f86e(ajc$tjp_3);
                c();
            }
            catch(Throwable throwable)
            {
                TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_3);
                throw throwable;
            }
            TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_3);
        }
     
        public static void c()
        {
            try
            {
                TraceAspect.aspectOf().ajc$before$TraceAspect$1$b314f86e(ajc$tjp_4);
                System.out.println("C reached!");
            }
            catch(Throwable throwable)
            {
                TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_4);
                throw throwable;
            }
            TraceAspect.aspectOf().ajc$after$TraceAspect$2$b314f86e(ajc$tjp_4);
        }
     
        private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_0;
        private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_1;
        private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_2;
        private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_3;
        private static final org.aspectj.lang.JoinPoint.StaticPart ajc$tjp_4;
     
        static 
        {
            Factory factory = new Factory("Test.java", Class.forName("Test"));
            ajc$tjp_0 = factory.makeSJP("constructor-execution", 
                                        factory.makeConstructorSig("1--Test----"), 1);
            ajc$tjp_1 = factory.makeSJP("method-execution",
                                        factory.makeMethodSig("9-main-Test-[Ljava.lang.String;:-args:--void-"), 4);
            ajc$tjp_2 = factory.makeSJP("method-execution",
                                        factory.makeMethodSig("9-a-Test----void-"), 8);
            ajc$tjp_3 = factory.makeSJP("method-execution",
                                        factory.makeMethodSig("9-b-Test----void-"), 12);
            ajc$tjp_4 = factory.makeSJP("method-execution",
                                        factory.makeMethodSig("9-c-Test----void-"), 16);
        }
    }