Around Advice Example in Spring AOP

Around advice in Spring

In this example, we will see a simple example of around-advice. To write this advice, we take the help of MethodInterceptor interface.
Around Advice as the name says it, this advice executes both before and after the method execution.
In simple words, around-advice is nothing more than piece of code that executes before the method invocation and after the method invocation. Therefore, we can call it as a combination of before and after advice.

Theme of the application

The theme of the application is to illustrate around-advice. As this advice is executed before and after the method call, you can restrict when the method should execute and what value it should return. Or simply, you can use this for logging purposes or to know the execution time of the method.
In this example, we will come to know how much time the method has taken to execute by starting a stop watch before method invocation and stopping it after method call. For this, we will be using StopWatch class from org.springframework.util package.
 

Create a project in eclipse

  1. File -> New -> Project -> Java Project
  2. Give the project name spring35 and click Finish 
  3. Now, the project is created.
  4. Under the Project Explorer (in the sidebar) you will see spring35. If you aren't able to see Project Explorer, go to Window menu -> Show view -> Project Explorer.
  5. Right click on the spring35 and click Properties
  6. On the left side, click on Java Build Path.
  7. Select the Libraries tab and then click on Add External Jars
  8. Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
  9. Click on OK and then you are read

To create a class

In the Project Explorer, navigate to spring35 and right click on spring35. Then go to New -> Class and give the name of the class as defined below.
 

Project structure 


WorkerBean.java 

This is a bean class that contains the method for which the around advice is given.
package spring35;

public class WorkerBean {

    public void work(long l)
    {
        for(long i=0;i<l;i++)
        {
            System.out.print("");
        }
    }
   
}
 
This class contains only a single method work(long) that takes the no. of iterations and prints an empty string as we don't want to fill the console with lengthy stuff.

WorkerBeanProfiler.java - Around Advice

This is the class that contains the advice code.
package spring35;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.StopWatch;

public class WorkerBeanProfiler implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
       
        // Create a StopWatch object
        StopWatch watch=new StopWatch();
       
        // Start the watch
        watch.start();
       
        // Call the method
        Object meth=mi.proceed();
       
        // Stop the watch
        watch.stop();
       
        // Display the time
        displayInfo(watch,mi);
       
        return meth;
    }
   
    public static void displayInfo(StopWatch watch,MethodInvocation mi)
    {
        // Get the method name and the argument
        String name=mi.getMethod().getName()+"("+mi.getArguments()[0]+")";
       
        // Get the total time in ms
        System.out.println(name+" took "+watch.getTotalTimeMillis()+" ms");
    }

}

The invoke() method is present in the MethodInterceptor interface. This method takes only a single argument MethodInterceptor which contains a main method proceed() which will execute the method.
So, we can call the proceed() method whenever we want to.

This object also contains methods such as getMethod() to get Method object, getArguments() which returns the argument values passed to the method.

SpringPrg.java - Main class

package spring35;

import org.springframework.aop.framework.ProxyFactory;

public class SpringPrg {

    public static void main(String args[])
    {
        // Create target object
        WorkerBean wb=new WorkerBean();
       
        // Create the advice object for target
        WorkerBeanProfiler wbp=new WorkerBeanProfiler();
       
        ProxyFactory pf=new ProxyFactory();
       
        // Set the target object
        pf.setTarget(wb);
       
        // Add the profiling advice
        pf.addAdvice(wbp);
       
        // Get the proxied bean object
        WorkerBean bean=(WorkerBean)pf.getProxy();
       
        // Start the work
        bean.work(100000L);
    }
   
}

In this class, we have created a target bean object, a ProxyFactory object and set the target object to the bean object, create the advice object and add that advice.
The getProxy() method returns the bean object whose for whose methods the advice will be applied.

The work() method when call from the object bean will execute the advice code. When you invoke work() from wb then the method will not print the time taken i.e. the advice is not executed.

Also see Method before advice and after returning advice

No comments: