Tuesday, May 11, 2010

AspectJ and @AspectJ without Spring using Maven

AspectJ offers two syntaxes. The first one is with the AspectJ syntax, another programming language. The second one is the @Aspect, which is set of annotations. With @AspectJ, our plain Java IDE will work just fine. There is no need to install AspectJ plugin or anything of that sort. For those obvious reasons, my preference is to use @AspectJ, the only catch is that it needs to run on Java 5 and above.

Here is a brief introduction how to setup AspectJ and @AspectJ without Spring using Maven.

Using AspectJ

LoggingAspect.aj
package myproject;

public aspect LoggingAspect {

    pointcut logging() : execution(* HelloWorld.sayHello(..));

    Object around() : logging() {
        System.out.println("Before " + thisJoinPointStaticPart.getSignature());
        Object ret = proceed();
        System.out.println("After " + thisJoinPointStaticPart.getSignature());

        return ret;
    }
}
The thisJoinPointStaticPart is one of the variables available in AspectJ.

or

Using @AspectJ

LoggingAspect.java
package myproject;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {

    @Pointcut("execution(* HelloWorld.sayHello(..))")
    public void logging() {}

    @Around("logging()")
    public Object logging(ProceedingJoinPoint thisJoinPoint) throws Throwable {
        System.out.println("Before " + thisJoinPoint.getSignature());
        Object ret = thisJoinPoint.proceed();
        System.out.println("After " + thisJoinPoint.getSignature());

        return ret;
    }
}
Unlike the AspectJ syntax, we need to include ProceedingJoinPoint argument to get something similar to thisJoinPointStaticPart in AspectJ syntax.

The Maven project requires Maven AspectJ plugin.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>myproject</groupId>
<artifactId>aspectj-project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainclass>myproject.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

HelloWorld.java
package myproject;

public class HelloWorld {

    public void sayHello(String message) {
        System.out.println(message);
    }
}

Main.java
package myproject;

public class Main {

    public static void main(String[] args) {
        HelloWorld helloWorld = new HelloWorld();
        helloWorld.sayHello("Hello World!");
        helloWorld.sayHello("Bye World!");
    }
}

To run, just execute 'mvn clean package exec:java'.

1 comment:

  1. Hello, could take a doubt?

    When the aspect is called?

    Your example only returns:

    Hello World!
    Bye World!
     
    I should not have run:

    System.out.println ("Before" + thisJoinPointStaticPart.getSignature());

    System.out.println ("After" + thisJoinPointStaticPart.getSignature());

    Thank you!

    ReplyDelete