package org.bk.inventory.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @Aspect public class AuditAspect { private static Logger logger = LoggerFactory.getLogger(AuditAspect.class); @Pointcut("execution(* org.bk.inventory.service.*.*(..))") public void serviceMethods(){ // } @Before("serviceMethods()") public void beforeMethod() { logger.info("before method"); } @Around("serviceMethods()") public Object aroundMethod(ProceedingJoinPoint joinpoint) { try { long start = System.nanoTime(); Object result = joinpoint.proceed(); long end = System.nanoTime(); logger.info(String.format("%s took %d ns", joinpoint.getSignature(), (end - start))); return result; } catch (Throwable e) { throw new RuntimeException(e); } } @After("serviceMethods()") public void afterMethod() { logger.info("after method"); } }
The @Aspect annotation on the class identifies it as an aspect definition. It starts by defining the pointcuts:
@Pointcut("execution(* org.bk.inventory.service.*.*(..))") public void serviceMethods(){}The above basically identifies all the methods of all types in org.bk.inventory.service package, this pointcut is identified by the name of the method on which the annotation is placed - in this case "serviceMethods". Next, the advice is defined using the @Before(serviceMethods()), @After(serviceMethods()) and @Around(serviceMethods()) annotation and the specifics of what needs to happen is the body of the methods with those annotations. Spring AOP natively understands the @AspectJ annotations, if this Aspect is defined as a bean:
<bean id="auditAspect" class="org.bk.inventory.aspect.AuditAspect" />Spring would create a dynamic proxy to apply the advice on all the target beans identified as part of the pointcut notation.
Links to all sessions on AOP:
AOP Session 1 - Decorator Pattern using Java Dynamic Proxies
AOP Session 2 - Using Spring AOP - xml based configuration
AOP Session 3 - Using Spring AOP - @AspectJ based configuration - with/without compile time weaving
AOP Session 4 - Native AspectJ with compile time weaving
AOP Session 5 - Comprehensive Example