Pages

Tuesday, September 11, 2018

AspectJ + Custom Annotation + Gradle (Without Spring)

Recently I had to create an aspect to run before and after an annotated method was executed.
The first thing I thought was to just use Spring, but I was told that the devices where this software was going to run have limited resources so Spring would not an option because of it's large memory footprint.

After looking around the internet for a while I decided to do it just by using the aspectJ framework on it's own.

This is how I configured my gradle file
group 'com.javing.customAnnotations'
version '1.0-SNAPSHOT'

project.ext {
    aspectjVersion = '1.8.4'
}

apply plugin: 'java'
apply plugin: 'aspectj.gradle'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath "gradle.plugin.aspectj:gradle-aspectj:0.1.6"
    }
}

dependencies {
    compile 'org.aspectj:aspectjrt:1.8.4'
    compile 'org.aspectj:aspectjweaver:1.8.4'
    compile 'org.aspectj:aspectjtools:1.8.4'
    compile 'junit:junit:4.12'
}


I created a custom annotation which will later allow me to trigger the aspect.
package spike;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HelloAnnotation {

    public boolean isRun() default true;

}


I placed the annotation on the methods I want the aspect to run around
package spike;

public class HelloApp {

    public static void main(String[] args) {
        HelloApp helloApp = new HelloApp();
        helloApp.work();
    }

    @HelloAnnotation
    public void work() {
        System.out.println("Hello world!");
    }
}


Finally I created the logic of the aspect
package spike;

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

@Aspect
public class HelloAspect {

    @Around("execution(* *(..)) && @annotation(spike.HelloAnnotation)")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("Before");
        Object proceed = pjp.proceed();
        System.out.println("After");
        return proceed;
    }

}

In order to see this working in the IntelliJ editor you have to make sure you enable the Gradle Test Runner.



Share with your friends