Monday, April 6, 2015

StopWatch with annotations to Profile methods using Spring Aspect Oriented Programming (AOP)

The following example is a way to measure the execution time for methods using Spring Aspect Oriented Programming (AOP).

First we need to create a new annotation:

import java.lang.annotation.*;

public @interface ProfileExecution 



Then we can create our aspect:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch; 

public class ProfileExecutionAspect {

 private static final Logger logger = LoggerFactory.getLogger(ProfileExecutionAspect.class);

 @Pointcut(value="execution(public * *(..))")
 public void anyPublicMethod() { }

 @Around("anyPublicMethod() && @annotation(ProfileExecution)")
 public void profileExecuteMethod(ProceedingJoinPoint jointPoint) throws Throwable {
 Signature signature = jointPoint.getSignature();
 String methodName = signature.toShortString();

 StopWatch stopWatch = new StopWatch(ProfileExecutionAspect.class.getName());



We also need to annotate our configuration file with @EnableAspectJAutoProxy and create a @Bean of our aspect type ProfileExecutionAspect.
import org.springframework.context.annotation.*;

public class Application {
 public ProfileExecutionAspect profileExecutionAspect() {
 return new ProfileExecutionAspect();

I know that some people will argue that its better to use spring xml configuration with aop but personally i prefer to use annotations.

Now you can use the @ProfileExecution to annotate any public method on a bean managed by spring container to get profile information on logger:

21:15:39.811 [main] INFO test.ProfileExecutionAspect - StopWatch 'test.ProfileExecutionAspect': running time (millis) = 10
ms     %     Task name
00010  100%  TestClass.testMethod()
For this sample to run you can use the following dependencies on your maven pom.xml file:

1 comment:

  1. this aspect (ProfileExecutionAspect) is not working for all the types, it will fail for all the methods that return types with not null support (for example: public boolean hello()).

    The aspect should return always a result:

    Object result = jointPoint.proceed();

    Anyway is a very good example.