How to declare Around Advice using @AspectJ


This example shows how to use annotations to write an aspect using @AspectJ feature which was introduced in AspectJ 5. With this we do not need to define the advices and pointcuts in XML file.

In following example we have written an aspect named OurAspect.java which contains a advice named ourAroundAdvice().

Around advice is a combination of before, after-returning and after-throwing advices. Around advice is wrapped around a method call and called both before and after of a method execution. The difference is that in before and after advices there are two separate advices but here there is only one advice containing logic of all three (before, after-returning and after-throwing) advices.

Steps:

1) Write EmployeeService interface and its implementation EmployeeServiceImpl.
2) Write MainApp class which use methods of  EmployeeService interface.
3) Write aspect class named OurAspect.java using annotations.
4) Enabling @AspectJ support in XML file

Technologies used

1) Spring-framework-3.0.6.RELEASE
2) Eclipse Java EE IDE Helios Release (Eclipse version 3.6)
3) Java SE 6




Code

EmployeeService.java

 package examples.springaop.anno;

public interface EmployeeService{
  
    public void addEmployee();
    public String getEmployeebyName(String id);
  
}

EmployeeServiceImpl.java

package examples.springaop.anno;

public class EmployeeServiceImpl implements EmployeeService{
   
    public void addEmployee(){
       
        System.out.println("In the addEmployee() method.");
       
       
    }
    public String getEmployeebyName(String id){
       
        System.out.println("In the getEmployeebyName() method.\n");
       

        if(id==null)
            throw new NullPointerException("ID cannot be null!");
       
        String empName = "Name"+id;
        return empName;
       
       
    }
   
}

MainApp.java

package examples.springaop.anno;

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

public class MainApp{
public static void main(String args[]){
   
    ApplicationContext appContext = new ClassPathXmlApplicationContext("resources/ApplicationContext.xml");
    EmployeeService empService = (EmployeeService)appContext.getBean("empService");
   

    System.out.println("First Call to method :");
   
    empService.getEmployeebyName("id1");
    System.out.println("-----------------------");   
   
    /*Causing exception to be thrown by this method*/
    System.out.println("Second Call to method :");

    empService.getEmployeebyName(null);
}
}

OurAspect.java

 package examples.springaop.anno;

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

@Aspect
public class OurAspect{

@Pointcut("execution(* examples.springaop.xml.EmployeeService.getEmployeebyName(..))")
public void getEmpPointcut(){
  
}

@Around("getEmpPointcut()")
 public void ourAroundAdvice(ProceedingJoinPoint method){
          System.out.println("Before-Advice Part:This is called before the method exceution.\n");
    
     try {
        method.proceed();
      
        System.out.println("After-Returning-Advice Part: This is called after the method returns nomally.\n");
    } catch (Throwable e) {
        System.out.println("After-Throwing-Advice Part: This is called after the method throws exception.\n");
    }
    
    
 }
}

Here we have used @Aspect annotation on java class OurAspect  to declare it as an aspect.

Next we have used @Pointcut annotation to declare pointcuts. @Pointcut is declared on methods. Here method names will be treated as pointcut ids, similar to what we do in

tag.(see example).

We have used @Around annotation to mark around advice.

Note that unlike other advices, Around advice takes one parameter of type ProceedingJoinPoint interface as:

 public void ourAroundAdvice(ProceedingJoinPoint method){
// logic for before advice
method.proceed();
// logic for After advice
}

This parameter represents the target method on which advice has been applied.
Also note how we called the target method inside the around advice using proceed() method.


ApplicationContext.xml
<?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"

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">

<bean id="empService" class="examples.springaop.anno.EmployeeServiceImpl"/>

<bean id="empAspect" class="examples.springaop.anno.OurAspect"/>

<aop:aspectj-autoproxy/>

</beans>

For enabling @AspectJ support we have added following in XML file.

<aop:aspectj-autoproxy/>

This will create proxies for the methods which are specified in pointcuts so that advice logic would be called before/after the method execution.

Note here pointcuts and advices are not defined in XML file.


Output

First Call to method :
Before-Advice Part:This is called before the method exceution.
In the getEmployeebyName() method.
After-Returning-Advice Part: This is called after the method returns nomally.
-----------------------
Second Call to method :
Before-Advice Part:This is called before the method exceution.
In the getEmployeebyName() method.
After-Throwing-Advice Part: This is called after the method throws exception.


Note that in second call to getEmployeebyName() method instead  of After-returning advice After-Throwing advice has been called because here getEmployeebyName() method has thrown an exception.

Jars Used

org.springframework.context-3.0.6.RELEASE.jar
org.springframework.core-3.0.6.RELEASE.jar
org.springframework.beans-3.0.6.RELEASE.jar
commons-logging-1.1.1.jar
org.springframework.asm-3.0.6.RELEASE.jar
org.springframework.aop-3.0.6.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
org.springframework.expression-3.0.6.RELEASE.jar
aspectjweaver-1.6.8.jar



I would like to know your comments and if you liked the article then please share it on social networking buttons.


1 comment: