Spring AOP AspectJ Annotation Example

In this post, we will see Spring AOP AspectJ Annotation examples.
If you are not familiar with Spring AOP terminology, you may go through Spring Aspect oriented programming(AOP) tutorial.
Following are the AspectJ annotations which we are going to use to implement Spring AOP.
@Aspect : To declare a class as Aspect.
Annotations which are used to create Advices are:
@Before : @Before annotation is used to create before advice. It executes before actual method execution (Join points)
@AfterReturning: This annotation is used to create return advice. It executes after a method execution completes without any exception.
@AfterThrowing: This annotation is used to create After throwing advice, it executes if method exits by throwing an exception.
@After : This annotation is used to create after advice, it executes after a method execution  regardless of outcome.
@Around : This annotation is used to create around advice,  It executes before and after a join point.

This may be confusing right now but once you implement an example, it will be clear.

@Before  :

lets say you have some business logic class (BusinessLogic.java) and you want to do logging before execution of getBusinessLogic method of this class.
package org.arpit.java2blog;

public class BusinessLogic {
 
 public void getBusinessLogic() {
  System.out.println("*****************");
  System.out.println("In Business Logic method");
  System.out.println("*****************");
 }
}
Now we will create aspect class
package org.arpit.java2blog;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

 @Before("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingBeforeBusinessLogic(JoinPoint joinPoint) {

  System.out.println("loggingBeforeBusinessLogic() is running!");
  System.out.println("Before execution of method : " + joinPoint.getSignature().getName());
 }

}
execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..)) is pointcut expression. It denotes execution of method loggingBeforeBusinessLogic before exection of getBusinessLogic method of BusinessLogic class.
Lets do xml configuaration of above beans in spring-config.xml.
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
 http://www.springframework.org/schema/aop 
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

 <aop:aspectj-autoproxy />
 <bean id="businessLogic" class="org.arpit.java2blog.BusinessLogic">
 </bean>
 <!-- Aspect -->
 <bean id="logAspect" class="org.arpit.java2blog.LoggingAspect" />

</beans>
Create main class named SpringAOPMain to execute the application
package org.arpit.java2blog;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringAOPMain {

    public static void main(String[] args) {
        ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
        BusinessLogic businessLogic = (BusinessLogic) appContext.getBean("businessLogic");
        businessLogic.getBusinessLogic();      
    }
}
When you run above program, you will get below output:
Jul 21, 2016 10:01:14 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@24174be7: startup date [Thu Jul 21 22:01:14 IST 2016]; root of context hierarchy
Jul 21, 2016 10:01:14 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
loggingBeforeBusinessLogic() is running!
Before execution of method : getBusinessLogic
*****************
In Business Logic method
*****************

@After:

I am replacing @Before method in LoggingAspect.java with @After annotated method.This method will execute after execution of actual business logic, so LoggingAspect.java will look something like this.
package org.arpit.java2blog;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {

@After("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {

  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
}
When you run SpringAOPMain.java again, you will get below output:
Jul 21, 2016 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu Jul 21 22:24:26 IST 2016]; root of context hierarchy
Jul 21, 2016 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*****************
In Business Logic method
*****************
loggingAfterBusinessLogic() is running!
After execution of method : getBusinessLogic
As you can see in above output, loggingAfterBusinessLogic executed after getBusinessLogic method

@AfterReturning:

I am replacing @After with @AfterReturning in above LoggingAspect.java.This method will execute after execution of actual business logic but only if it successfully returns.
package org.arpit.java2blog;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

@AfterReturning("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {

  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
}
When you run SpringAOPMain.java again, you will get below output:
Jul 21, 2016 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu Jul 21 22:24:26 IST 2016]; root of context hierarchy
Jul 21, 2016 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*****************
In Business Logic method
*****************
loggingAfterBusinessLogic() is running!
After execution of method : getBusinessLogic

@AfterThrowing: 

Lets add one more method with @AfterThrowing annotation. It will execute if any exception occurs in getBusinessLogic method.
LoggingAspect.java
package org.arpit.java2blog;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class LoggingAspect {
 
 @AfterReturning("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogic(JoinPoint joinPoint) {

  System.out.println("loggingAfterBusinessLogic() is running!");
  System.out.println("After execution of method : " + joinPoint.getSignature().getName());
 }
 
 @AfterThrowing("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingAfterBusinessLogicException(JoinPoint joinPoint) {

  System.out.println("Exception occurred in getBusinessLogic method");
  
 }

}
Now throw RuntimeException from getBusinessLogic to test @AfterThrowing exception. BusinessLogic.java
package org.arpit.java2blog;

public class BusinessLogic {
 
 public void getBusinessLogic() {
  System.out.println("*****************");
  System.out.println("In Business Logic method");
  System.out.println("*****************");
  throw new RuntimeException();
 }
}

When you run SpringAOPMain.java , you will get below output:
Jul 21, 2016 10:34:55 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu Jul 21 22:34:55 IST 2016]; root of context hierarchy
Jul 21, 2016 10:34:55 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
*****************
In Business Logic method
*****************
Exception occurred in getBusinessLogic method
Exception in thread "main" java.lang.RuntimeException
 at org.arpit.java2blog.BusinessLogic.getBusinessLogic(BusinessLogic.java:9)
 at org.arpit.java2blog.BusinessLogic$$FastClassBySpringCGLIB$$3d288cb4.invoke(<generated>)
 at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
 at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
 at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
 at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
 at org.arpit.java2blog.BusinessLogic$$EnhancerBySpringCGLIB$$1fbd989f.getBusinessLogic(<generated>)
 at org.arpit.java2blog.SpringAOPMain.main(SpringAOPMain.java:10)

As you can see loggingAfterBusinessLogicException got executed as there is exception in business logic.

@Around:

Method with @Around will get called before and after execution of business logic.
You need to call reference of ProceedingJoinPoint and call proceed method to execute actual business logic.
package org.arpit.java2blog;

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

@Aspect
public class LoggingAspect {

 @Around("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))")
 public void loggingAroundBusinessLogic(ProceedingJoinPoint joinPoint) throws Throwable {
  System.out.println("Before calling actual business logic"); // Before running actual business logicic
  joinPoint.proceed(); // business logic method get executed 
  System.out.println("After calling actual business logic"); // After running actual business logic
 }
}
When you run SpringAOPMain.java , you will get below output:
Jul 21, 2016 11:04:10 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu Jul 21 23:04:10 IST 2016]; root of context hierarchy
Jul 21, 2016 11:04:10 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
Before calling actual business logic
*****************
In Business Logic method
*****************
After calling actual business logic

Written by Arpit:

If you have read the post and liked it. Please connect with me on Facebook | Twitter | Google Plus

 

Java tutorial for beginners Copyright © 2012