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
- File -> New -> Project -> Java Project
- Give the project name spring35 and click Finish
- Now, the project is created.
- Under the Project Explorer (in the sidebar) you will see spring35. If you aren't able to see Project Explorer, go to Window sajian -> Show view -> Project Explorer.
- Right click on the spring35 and click Properties
- On the left side, click on Java Build Path.
- Select the Libraries tab and then click on Add External Jars
- Now, add these jar files starting with: spring-core, aop-alliance, spring-aop, commons-logging
- 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.
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 sasaran object
WorkerBean wb=new WorkerBean();
// Create the advice object for target
WorkerBeanProfiler wbp=new WorkerBeanProfiler();
ProxyFactory pf=new ProxyFactory();
// Set the sasaran 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 sasaran bean object, a ProxyFactory object and set the sasaran 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