Spring AOP with AspectJ Annotation Configuration Example

As we have already seen the AOP advise methods and its implementation through XML.

Let’s discuss AOP advises with annotation

In order to achieve this, we need to follow below steps

Annotate our aspect class with @Aspect annotation.
We need to define the aspect as a bean in spring xml file
We need to define the advise methods using annotation like @Before,@After etc

 

Project structure looks like below

AOP_Annotation

 

Create a pom.xml as below

  1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  2.   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  3.   <modelVersion>4.0.0</modelVersion>
  4.  
  5.   <groupId>Spring</groupId>
  6.   <artifactId>SpringAOP</artifactId>
  7.   <version>0.0.1-SNAPSHOT</version>
  8.   <packaging>jar</packaging>
  9.  
  10.   <name>SpringAOP</name>
  11.   <url>http://maven.apache.org</url>
  12.  
  13.   <properties>
  14.     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  15.   </properties>
  16.  
  17.   <dependencies>
  18.   <dependency>
  19.     <groupId>org.springframework</groupId>
  20.     <artifactId>spring-core</artifactId>
  21.     <version>4.2.4.RELEASE</version>
  22. </dependency>
  23.   <dependency>
  24.     <groupId>org.springframework</groupId>
  25.     <artifactId>spring-context</artifactId>
  26.     <version>4.2.4.RELEASE</version>
  27. </dependency>
  28. <dependency>
  29.     <groupId>org.aspectj</groupId>
  30.     <artifactId>aspectjrt</artifactId>
  31.     <version>1.7.3</version>
  32. </dependency>
  33.  
  34. <dependency>
  35.     <groupId>org.aspectj</groupId>
  36.     <artifactId>aspectjweaver</artifactId>
  37.     <version>1.7.2</version>
  38. </dependency>
  39.  
  40.     <dependency>
  41.       <groupId>junit</groupId>
  42.       <artifactId>junit</artifactId>
  43.       <version>3.8.1</version>
  44.       <scope>test</scope>
  45.     </dependency>
  46.   </dependencies>
  47. </project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>Spring</groupId>
  <artifactId>SpringAOP</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>SpringAOP</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
  <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
  <dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjrt</artifactId>
	<version>1.7.3</version>
</dependency>

<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.7.2</version>
</dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

 

Lets first create a SimpleCalculator class as below

  1. package com.kb;
  2. public class SimpleCalculator {
  3.     public int add(int x,int y){
  4.         System.out.println("inside Add");
  5.         return x+y;
  6.     }
  7.    
  8.     public int subtract(int x,int y){
  9.         System.out.println("inside subtract");
  10.         return x-y;
  11.     }
  12. }
package com.kb;
public class SimpleCalculator {
	public int add(int x,int y){
		System.out.println("inside Add");
		return x+y;
	}
	
	public int subtract(int x,int y){
		System.out.println("inside subtract");
		return x-y;
	}
}

Now Lets write our Aspect classes using annotations as below

First lets write Before aspect class as below

  1. package com.kb;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Before;
  6. import org.aspectj.lang.annotation.Pointcut;
  7.  
  8. @Aspect
  9. public class MyBeforeAspect {
  10.    
  11.     @Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
  12.     public void pointcutName(){}
  13.    
  14.       @Before("pointcutName()")//applying pointcut on before advice  
  15.         public void myadvice(JoinPoint jp)
  16.         {  
  17.             System.out.println("my before advice");  
  18.         }
  19. }
package com.kb;

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

@Aspect
public class MyBeforeAspect {
	
	@Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
	public void pointcutName(){}
	
	  @Before("pointcutName()")//applying pointcut on before advice  
	    public void myadvice(JoinPoint jp)
	    {  
	        System.out.println("my before advice");  
	    }
}

As you can see that , class is annotated with @Aspect to define this class as an Aspect.

We have defined pointcut expression using @Pointcut annotation by passing pointcut expression.
We have written empty method just to use it as a pointcut in the advice.

We have defined Before advise using @Before annotation by passing pointcut name which is “pointcutName” in our case.

Lets write After aspect class as below

  1. package com.kb;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.After;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Pointcut;
  7.  
  8. @Aspect
  9. public class MyAfterAspect {
  10.  
  11.     @Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
  12.     public void pointcutName(){}
  13.    
  14.       @After("pointcutName()")//applying pointcut on after advice  
  15.         public void myadvice(JoinPoint jp)
  16.         {  
  17.             System.out.println("my after advice");  
  18.         }
  19. }
package com.kb;

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

@Aspect
public class MyAfterAspect {

	@Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
	public void pointcutName(){}
	
	  @After("pointcutName()")//applying pointcut on after advice  
	    public void myadvice(JoinPoint jp)
	    {  
	        System.out.println("my after advice");  
	    }
}

As you can see that , class is annotated with @Aspect to define this class as an Aspect.

We have defined pointcut expression using @Pointcut annotation by passing pointcut expression.
We have written empty method just to use it as a pointcut in the advice.

We have defined After advise using @After annotation by passing pointcut name which is “pointcutName” in our case.

Lets write AfterReturning aspect class as below

  1. package com.kb;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.AfterReturning;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Pointcut;
  7.  
  8. @Aspect
  9. public class MyAfterReturningAspect {
  10.     @Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
  11.     public void pointcutName(){}
  12.    
  13.       @AfterReturning("pointcutName()")//applying pointcut on after returning //advice  
  14.         public void myadvice(JoinPoint jp)
  15.         {  
  16.             System.out.println("my after returning advice");  
  17.         }
  18. }
package com.kb;

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

@Aspect
public class MyAfterReturningAspect {
	@Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
	public void pointcutName(){}
	
	  @AfterReturning("pointcutName()")//applying pointcut on after returning //advice  
	    public void myadvice(JoinPoint jp)
	    {  
	        System.out.println("my after returning advice");  
	    }
}

As you can see that , class is annotated with @Aspect to define this class as an Aspect.

We have defined pointcut expression using @Pointcut annotation by passing pointcut expression.
We have written empty method just to use it as a pointcut in the advice.

We have defined AfterReturning advise using @AfterReturning annotation by passing pointcut name which is “pointcutName” in our case.

Lets write AfterThrowing aspect class as below

  1. package com.kb;
  2.  
  3. import org.aspectj.lang.JoinPoint;
  4. import org.aspectj.lang.annotation.AfterThrowing;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Pointcut;
  7.  
  8. @Aspect
  9. public class MyAfterThrowingAspect {
  10.  
  11.     @Pointcut("execution(* com.kb.SimpleCalculatorThrowsException.*(..))")
  12.     public void pointcutName(){}
  13.    
  14.       @AfterThrowing("pointcutName()")//applying pointcut on after throwing  //advice  
  15.         public void myadvice(JoinPoint jp)
  16.         {  
  17.             System.out.println("my after throwing advice");  
  18.         }
  19. }
package com.kb;

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

@Aspect
public class MyAfterThrowingAspect {

	@Pointcut("execution(* com.kb.SimpleCalculatorThrowsException.*(..))")
	public void pointcutName(){}
	
	  @AfterThrowing("pointcutName()")//applying pointcut on after throwing  //advice  
	    public void myadvice(JoinPoint jp)
	    {  
	        System.out.println("my after throwing advice");  
	    }
}

As you can see that , class is annotated with @Aspect to define this class as an Aspect.

We have defined pointcut expression using @Pointcut annotation by passing pointcut expression.
We have written empty method just to use it as a pointcut in the advice.

We have defined AfterThrowing advise using @AfterThrowing annotation by passing pointcut name which is “pointcutName” in our case.

Also define the class which actually throws an exception so that above advice will be called

  1. package com.kb;
  2. public class SimpleCalculatorThrowsException {
  3.  
  4.     public int add(int x,int y){
  5.         System.out.println("inside Add");
  6.         throw new RuntimeException();
  7.     }
  8. }
package com.kb;
public class SimpleCalculatorThrowsException {

	public int add(int x,int y){
		System.out.println("inside Add");
		throw new RuntimeException();
	}
}

Let’s write Around aspect class as below

  1. package com.kb;
  2.  
  3. import org.aspectj.lang.ProceedingJoinPoint;
  4. import org.aspectj.lang.annotation.Around;
  5. import org.aspectj.lang.annotation.Aspect;
  6. import org.aspectj.lang.annotation.Pointcut;
  7.  
  8. @Aspect
  9. public class MyAroundAspect {
  10.    
  11.     @Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
  12.     public void pointcutName(){}
  13.    
  14.      @Around("pointcutName()")//applying pointcut on before advice  
  15.     public Object myAdvice(ProceedingJoinPoint jp){
  16.         System.out.println("Around -- Before the method "+jp.getSignature().getName()+" execution");
  17.         Object[] args=null;
  18.         Object value=null;
  19.         try {
  20.             args=jp.getArgs();
  21.             if((Integer)args[0] == 10){
  22.                 value= jp.proceed();
  23.             }
  24.         } catch (Throwable e) {
  25.             e.printStackTrace();
  26.         }
  27.         System.out.println("Around -- After the method "+jp.getSignature().getName()+" execution");
  28.         return value;
  29.     }
  30.  
  31. }
package com.kb;

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

@Aspect
public class MyAroundAspect {
	
	@Pointcut("execution(* com.kb.SimpleCalculator.*(..))")
	public void pointcutName(){}
	
	 @Around("pointcutName()")//applying pointcut on before advice  
	public Object myAdvice(ProceedingJoinPoint jp){
		System.out.println("Around -- Before the method "+jp.getSignature().getName()+" execution");
		Object[] args=null;
		Object value=null;
		try {
			args=jp.getArgs();
			if((Integer)args[0] == 10){
				value= jp.proceed();
			}
		} catch (Throwable e) {
			e.printStackTrace();
		}
		System.out.println("Around -- After the method "+jp.getSignature().getName()+" execution");
		return value;
	}

}

As you can see that , class is annotated with @Aspect to define this class as an Aspect.

We have defined pointcut expression using @Pointcut annotation by passing pointcut expression.
We have written empty method just to use it as a pointcut in the advice.

We have defined Around advise using @Around annotation by passing pointcut name which is “pointcutName” in our case

Now after defining all the Aspects using annotations, we need to make them as spring beans by defining them in spring configuration file.

Lets create spring configuration xml file

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
  4.     xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans
  6.        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
  7.        http://www.springframework.org/schema/aop  
  8.         http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
  9.        http://www.springframework.org/schema/context
  10.         http://www.springframework.org/schema/context/spring-context-3.2.xsd">
  11.  
  12.     <aop:aspectj-autoproxy />
  13.  
  14.     <bean id="simpleCalc" class="com.kb.SimpleCalculator"/>
  15.    
  16.     <bean id="simpleCalcException" class="com.kb.SimpleCalculatorThrowsException"/>
  17.    
  18.     <bean id="myBeforeAspect" class="com.kb.MyBeforeAspect" />
  19.     <bean id="myAfterAspect" class="com.kb.MyAfterAspect" />
  20.     <bean id="myAfterReturningAspect" class="com.kb.MyAfterReturningAspect" />
  21.     <bean id="myAfterThrowingAspect" class="com.kb.MyAfterThrowingAspect" />
  22.     <bean id="myAroundAspect" class="com.kb.MyAroundAspect" />
  23.    
  24. </beans>
<?xml version="1.0" encoding="UTF-8"?>
<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"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/aop   
    	http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
        http://www.springframework.org/schema/context
  		http://www.springframework.org/schema/context/spring-context-3.2.xsd">

	<aop:aspectj-autoproxy />

	<bean id="simpleCalc" class="com.kb.SimpleCalculator"/>
	
	<bean id="simpleCalcException" class="com.kb.SimpleCalculatorThrowsException"/>
	
	<bean id="myBeforeAspect" class="com.kb.MyBeforeAspect" />
	<bean id="myAfterAspect" class="com.kb.MyAfterAspect" />
	<bean id="myAfterReturningAspect" class="com.kb.MyAfterReturningAspect" />
	<bean id="myAfterThrowingAspect" class="com.kb.MyAfterThrowingAspect" />
	<bean id="myAroundAspect" class="com.kb.MyAroundAspect" />
	
</beans>

Now lets run the AOPTest class to see the output

  1. package com.kb;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class AOPTest {
  7.  
  8.     public static void main(String[] args) {
  9.     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");  
  10.        SimpleCalculator calculator = (SimpleCalculator) context.getBean("simpleCalc");
  11.       int res1= calculator.add(10, 5);
  12.       System.out.println("addition result is "+res1);
  13.       System.out.println("............");
  14.       int res2= calculator.subtract(10, 5);
  15.       System.out.println("subtracted result is "+res2);
  16.     }
  17. }
package com.kb;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPTest {

	public static void main(String[] args) {
	ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");  
       SimpleCalculator calculator = (SimpleCalculator) context.getBean("simpleCalc"); 
      int res1= calculator.add(10, 5);
      System.out.println("addition result is "+res1);
      System.out.println("............");
      int res2= calculator.subtract(10, 5);
      System.out.println("subtracted result is "+res2);
	}
}

Observe the output

before each method got executed Before advice and Around advice got executed

after the method execution After,AfterReturning and Around advice got executed.

Now lets run the AOPTestException class to see the output

  1. package com.kb;
  2.  
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5.  
  6. public class AOPTestException {
  7.     public static void main(String[] args) {
  8.     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");  
  9.     SimpleCalculatorThrowsException calculator = (SimpleCalculatorThrowsException)       context.getBean("simpleCalcException");
  10.       int res1= calculator.add(10, 5);
  11.       System.out.println("addition result is "+res1);
  12.      
  13.     }
  14. }
package com.kb;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AOPTestException {
	public static void main(String[] args) {
	ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");  
	SimpleCalculatorThrowsException calculator = (SimpleCalculatorThrowsException)       context.getBean("simpleCalcException"); 
      int res1= calculator.add(10, 5);
      System.out.println("addition result is "+res1);
     
	}
}

Observe the output below

Output shows that AfterThrowing advice got executed when the method throws an exception

Download this project SpringAOP_Annotation.zip

About the Author

Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on