AOP Around advice is combination of all the other three advices which Spring AOP supports (before, after and throws advices). It is executed at all join points of method like before method executions starts, after method execution completes, and in case of any run time exception is raised.
So if you implement Around advice in your aspect, you can eliminate the need of other three advices, and hence Around advice is powerful advice compared to other advices.
Key points For AOP Around Advice :
- The Around Advice was given by open source framework called AOP alliance.
- Around Advice is a combination of before and after returning advices.
- In order to implement the Around Advice, we need to implement our classes from MethodInterceptor interface, and we need to override the invoke() method.
- Since the Around Advice is a combination of Before and After Advices, we can write our before and after logic in the invoke() method itself.
- In order to separate the before and after advices, we need to call proceed() method in invoke() method.
- The Around Advice is a very power full Advice, when comparing with individual Before and After Advices. Because, here we can catch the hold of the return value (as an Object) of the business method, and we can do modifications on the return values too.
- Another advantage of Around advice is, we can get the business method parameters too. If we want, we can modify them or we can remove them.
To create Around advice, you have to implement MethodInterceptor which is given by AOP Alliance and then you have to provide concrete implementation of invoke method. invoke() method has the object of MethodInvocation as parameter, which is also from AOP alliance.
As we discussed in the bullet points; You can access the method name using getMethod().getName(), and arguments as object array using getArguments(). To proceed with the execution of actual join point method we have to call proceed() method.
Steps to implement Around Advice :
Below are the steps to implement Around Advice
MethodInterceptor Implementation
- Create a class where you want to have your Around Advice and have the class implementing org.aopalliance.intercept.MethodInterceptor;
- Since you have implemented interface, override the interface method invoke()This method has MethodInvocation object as argument, so write your method body by accessing data from this document
i. Get method name by calling arg0.getMethod().getName()
ii. Get arguments array passed to join point method by calling arg0.getArguments()
iii. Call the join point method whenever you want to execute your business logic using arg0.proceed() - Target Object
Create Service class, and add business methods to it - Spring Config file
Create a bean for the Around Advice implementations as below:
<bean class="com.spring.aop.advices.AroundAdvice" id="aroundAdvice" />
- Create a bean for Target object as below :
<bean id="product" class="com.spring.aop.Product">
<property name="productId" value="101" />
<property name="productName" value="iPhone" />
</bean>
- Create a bean for
org.springframework.aop.framework.ProxyFactoryBean
and pass properties like target with your target bean id, proxyInterfaces with class path of interface your target bean implemented, and interceptorNames with bean ids of advice as shown below:
<bean id="productProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="product" />
<property name="proxyInterfaces" value="com.spring.aop.BaseProducts" />
<property name="interceptorNames">
<list>
<value>aroundAdvice</value
</list>
</property>
</bean>
Here is the Complete Example for AOP Around Advice.
Simple Example For AOP Around Advice :
Project Structure :
Create Business Interface :
BaseProducts.java
package com.spring.aop;
public interface BaseProducts {
int productId = 0;
String productName = "";
void buyProduct();
void sellProduct();
}
Create concrete class for business interface :
Product.java
package com.spring.aop;
public class Product implements BaseProducts {
private int productId;
private String productName;
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public void buyProduct() {
System.out.println("I am buying the Product : " + getProductName());
}
public void sellProduct() {
System.out.println("I am Selling the Product : " + getProductName());
}
}
Create Around Advice class :
AroundAdvice.java
package com.spring.aop.advices;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class AroundAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// TODO Auto-generated method stub
System.out.println("Method Name : " + arg0.getMethod().getName());
try {
System.out.println("Before Advice Called ");
Object object = arg0.proceed();
System.out.println("After Advice Called "+object);
return object;
} catch (Throwable e) {
throw e;
}
}
}
spring configuration :
appication-config.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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<bean id="product" class="com.spring.aop.Product">
<property name="productId" value="101" />
<property name="productName" value="iPhone" />
</bean>
<bean class="com.spring.aop.advices.AroundAdvice" id="aroundAdvice" />
<bean id="productProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="product" />
<property name="proxyInterfaces" value="com.spring.aop.BaseProducts" />
<property name="interceptorNames">
<list>
<value>aroundAdvice</value>
</list>
</property>
</bean>
</beans>
Run the Example :
Main.java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.spring.aop.BaseProducts;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application-config.xml");
BaseProducts product = (BaseProducts)context.getBean("productProxy");
System.out.println("**********");
product.sellProduct();
System.out.println("**********");
product.buyProduct();
System.out.println("**********");
}
}
Output :
**********
Method Name : sellProduct
Before Advice Called
I am Selling the Product : iPhone
After Advice Called
**********
Method Name : buyProduct
Before Advice Called
I am buying the Product : iPhone
After Advice Called
**********
Happy Learning 🙂