In this tutorial, we are going to learn about Spring AOP ThrowsAdvice. In the previous tutorial we had a discussion with spring AOP Before, After, Around Advices.
ThrowsAdvice is used if we want a specific action to be executed, when an exception is thrown inside a method. Briefly it is called by Spring IoC container whenever any runtime exception is raised.
To create throws advice you have to implement ThrowsAdvice interface and the class that has implemented have to explicitly implement below methods.
In fact afterThrowing() method has given in two different flavors.
- public void afterThrowing(Exception ex)
An object is created for run time exception and sent to this method
- public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
Here we have four arguments
- Method: method name where exception is raised
- Object[]: list of arguments passed to the method
- Object: object of Target class
- Exception: Runtime exception object
Here ThrowsAdvice is a marker interface and so you have to explicitly implement any of above two methods.
Steps to implement Throws Advice :
A. ThrowsAdvice Implementation :
- Create a class where you want to have a method to be called when exception is raised and have the class implementing org.springframework.aop.ThrowsAdvice
- Since you have implemented interface, override the interface method afterThrowing.
- This method has exception as argument, so write your method body as what you want to do when an exception is raised like sending mail, logging the exception etc..
B. Target Object
- Create Service class, and add business methods to it
- Create a scenario in any method say method1(), where some exception happens
C. Spring Config file
- Create a bean for the Throws Advice implementations as below:
<bean class="com.spring.aop.advices. id="throwsAdvice"/>
- 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 you 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>
<property name="target" ref="product" />
<property name="proxyInterfaces" value="com.spring.aop.BaseProd />
<property name="interceptorNames">
<list>
<value>aroundAdvice</value>
<value>throwsAdvice</value>
</list>
</property>
</bean>
Lets do the example on ThrowsAdvice :
ThrowsAdvice Advice Example :
Project Structure :
Create Business Interface :
BaseProducts.java
package com.spring.aop;
public interface BaseProducts {
int productId = 0;
String productName = "";
void buyProduct();
void sellProduct();
void throwsException();
}
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());
}
public void throwsException() {
throw new ArithmeticException();
}
}
Create AroundAdvice class : It is not mandatory for this example, to do some business activity we are creating this.
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 ");
return object;
} catch (Throwable e) {
throw e;
}
}
}
Creating ThrowsAdvice class :
MyThrowsAdvice.java
package com.spring.aop.advices;
import org.springframework.aop.ThrowsAdvice;
public class MyThrowsAdvice implements ThrowsAdvice {
public void afterThrowing(Exception ex) {
System.out.println("Executes After exception");
}
}
The afterThrowing(Exception ex) method called by IOC container, when ever the exception raised in application.
Create configuration :
application-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 class="com.spring.aop.advices.MyThrowsAdvice" id="throwsAdvice"/>
<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>
<value>throwsAdvice</value>
</list>
</property>
</bean>
</beans>
Run the application :
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");
product.sellProduct();
product.buyProduct();
product.throwsException();
}
}
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
Method Name : throwsException
Before Advice Called
Executes After exception
Exception in thread "main" java.lang.ArithmeticException
at com.spring.aop.Product.throwsException(Product.java:35)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
In the product class, we explicitly throws ArithmeticException
. So that Executes After exception
statement is executed in the above output.
Happy Learning 🙂