A simple application to demonstrate how to implement After Throwing Advice using @AspectJ Annotation-Driven AOP in Java.
Step 1:- Create a Interface Divide.java
Step 2:- DivisionImpl.java Service Implementation Class
Step 3:- After Throwing Advice Implementation class
Step 4 :- Spring Configuration file
Step 5:- Test class
Output of the program :
Step 1:- Create a Interface Divide.java
package com.hubberspot.aspectj.annotation.afterthrowingadvice; // Its a simple interface for the Division service. // It contains one single method called as divide(). // This method takes in two arguments both of the type // int. public interface Divide { public int divide(int a , int b); }
Step 2:- DivisionImpl.java Service Implementation Class
package com.hubberspot.aspectj.annotation.afterthrowingadvice; // It is the implementation class for the // Division service. It just calculates and returns // division of two numbers passed to it as arguments. // If denominator passed to it as zero than // new ArithmeticException() is thrown. public class DivideImpl implements Divide { @Override public int divide(int a, int b) { if(b != 0) { return a/b; } else { throw new ArithmeticException(); } } }
Step 3:- After Throwing Advice Implementation class
package com.hubberspot.aspectj.annotation.afterthrowingadvice; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; //@Aspect annotation treats this Java class as //Aspect. Its not ordinary POJO class. @Aspect public class AfterThrowingDivideAdvice { // Method afterThrowing() is a After Throwing advice // implemented by providing @AfterThrowing annotation. // This annotation takes in Pointcut expression, which // indicates when this advice executes. // This Pointcut expression tells that afterThrowing() advice // will execute after any exception is thrown from the method // divide of Divide interface. // The after advice takes in JoinPoint and an Object. JoinPoint // which here represents method execution and pointcut expression // takes in throwing property and makes it able to store, available // to the afterThrowing method. @AfterThrowing ( pointcut = "execution(* com.hubberspot.aspectj.annotation.afterthrowingadvice.Divide.divide(..))" , throwing = "exception" ) public void afterThrowing(JoinPoint joinPoint , Throwable exception) { System.out.println("Exception is thrown by divide method : "+ exception); } }
Step 4 :- Spring Configuration file
<?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.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd"> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- Implementation Class --> <bean id="divide" class="com.hubberspot.aspectj.annotation.afterthrowingadvice.DivideImpl" /> <bean id="afterThrowingAdvice" class="com.hubberspot.aspectj.annotation.afterthrowingadvice.AfterThrowingDivideAdvice" /> </beans> |
Step 5:- Test class
package com.hubberspot.aspectj.annotation.afterthrowingadvice; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DivisionTest { public static void main(String[] args) { // ApplicationContext is a Spring interface which // provides with the configuration for an application. // It provides us with all the methods that BeanFactory // provides. It loads the file resources in a older // and generic manner. It helps us to publish events to the // listener registered to it. It also provides quick support // for internationalization. It provides us with the object // requested, it reads the configuration file and provides // us with the necessary object required. // We are using concrete implementation of AbstractApplicationContext // here called as ClassPathXmlApplicationContext because this // bean factory reads the xml file placed in the classpath of // our application. We provide ClassPathXmlApplicationContext // with a configuration file called as after_throwing_advice.xml placed // at classpath of our application. ApplicationContext context = new ClassPathXmlApplicationContext("after_throwing_advice.xml"); // In order to get a object instantiated for a particular bean // we call getBean() method of ClassPathXmlApplicationContext // passing it the id for which the object is to be needed. // Here getBean() returns an Object. We need to cast it back // to the Divide object. Without implementing new keyword we // have injected object of Divide just by reading an xml // configuration file. Divide divide = (Divide)context.getBean("divide"); int result = divide.divide(10 , 5); System.out.println("Result = " + result); result = divide.divide(10, 0); System.out.println("Result = " + result); } }
Output of the program :