Aspect Oriented Programming allows you to “define cross-cutting concerns that can be applied across separate, very different, object models”. AOP complements Object Oriented Programming by increasing modularity with applying common behavior to multiple non-related object models. Basically, think about AOP as an interceptor for method calls, where you can add extra functionality. 

Spring AOP is one of the key components of Spring Framework. It is very easy to start with, and can be used for getting complicated things done very easy. For example, Spring Transactional Management is made possible using Spring AOP.

Here you will see how to add logging of method calls with Spring. On every call you can log method name, method arguments, returned object, as well as method execution time. So you can use AOP as a profiler, where you can check where are the bottlenecks of your application.

If you are concern if introducing of Spring AOP decrease performance, as you are adding overhead to execution of all your service calls, check this blog post. In the end, you can always disable aspects on production environment once you solve performance problems. You can also enable it or disable it dynamically if you think your log file will become cluttered.

Here are steps for easy starting with Spring AOP (if you are already using spring framework):

1. Add support for spring-aop and aspectj

If you are using maven, and not using spring-aop already, just add this two new dependencies.

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework.version}</version>
</dependency>

<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${org.aspectj.verision}</version>
</dependency>

2. Define your aspect and pointcuts

There are two ways two define aspects : With @Aspect annotation, or in Spring`s application.xml file. Here we`ll be using Spring annotation.
Just Create aspect class file as below. Also, to enable automatic generation of proxies, tag “<aop:aspectj-autoproxy/>” needs to be added in applicationContext.xml file.


@Component
@Aspect
public class MyAspect {

	private final Log log = LogFactory.getLog(this.getClass());

	@Around("execution(* com.foo.bar..*.*(..))")
	public Object logTimeMethod(ProceedingJoinPoint joinPoint) throws Throwable {

			StopWatch stopWatch = new StopWatch();
			stopWatch.start();

			Object retVal = joinPoint.proceed();

			stopWatch.stop();

			StringBuffer logMessage = new StringBuffer();
			logMessage.append(joinPoint.getTarget().getClass().getName());
			logMessage.append(".");
			logMessage.append(joinPoint.getSignature().getName());
			logMessage.append("(");
			// append args
			Object[] args = joinPoint.getArgs();
			for (int i = 0; i < args.length; i++) {
				logMessage.append(args[i]).append(",");
			}
			if (args.length > 0) {
				logMessage.deleteCharAt(logMessage.length() - 1);
			}

			logMessage.append(")");
			logMessage.append(" execution time: ");
			logMessage.append(stopWatch.getTotalTimeMillis());
			logMessage.append(" ms");
			log.info(logMessage.toString());
			return retVal;
	}

}

In this example, method calls are logged with execution time. You can check Spring’s AOP documentation which Joint Point, Advice, Pointcuts, etc. you can define for your application. For example if you want to log what method is returning, use @AfterReturnung Advice:

@AfterReturning(pointcut = "execution(* com.foo.bar..*.*(..))", returning = "retVal")
public void logAfterMethod(JoinPoint joinPoint, Object retVal) {
...
}

If you want to dynamically enable/disable logging, one way this can be done is introducing new flag in Logging Aspect. Than just add new Join point that will intercept your’s specific calls of changing this flag.

You can also completely disable aspects with just commenting Pointcut definition, or you can externalize this configuration using Spring.

0 comments