Table of Contents
If you are not familiar with Spring AOP terminology, you may go through Spring Aspect oriented programming(AOP) tutorial.
Following are the AspectJ annotations which we are going to use to implement Spring AOP.
@Aspect : To declare a class as Aspect.
Annotations which are used to create Advices are:
@Before :Â @Before annotation is used to create before advice. It executes before actual method execution (Join points)
@AfterReturning:Â This annotation is used to create return advice. It executes after a method execution completes without any exception.
@AfterThrowing: This annotation is used to create After throwing advice, it executes if method exits by throwing an exception.
@After : This annotation is used to create after advice, it executes after a method execution  regardless of outcome.
@Around : This annotation is used to create around advice,  It executes before and after a join point.
This may be confusing right now but once you implement an example, it will be clear.
@Before  :
lets say you have some business logic class (BusinessLogic.java) and you want to do logging before execution of getBusinessLogic method of this class.
1 2 3 4 5 6 7 8 9 10 11 12 |
package org.arpit.java2blog; public class BusinessLogic { public void getBusinessLogic() { System.out.println("*****************"); System.out.println("In Business Logic method"); System.out.println("*****************"); } } |
Now we will create aspect class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
package org.arpit.java2blog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingBeforeBusinessLogic(JoinPoint joinPoint) { System.out.println("loggingBeforeBusinessLogic() is running!"); System.out.println("Before execution of method : " + joinPoint.getSignature().getName()); } } |
execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..)) is pointcut expression. It denotes execution of method loggingBeforeBusinessLogic before exection of getBusinessLogic method of BusinessLogic class.
Lets do xml configuaration of above beans in spring-config.xml.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <aop:aspectj-autoproxy /> <bean id="businessLogic" class="org.arpit.java2blog.BusinessLogic"> </bean> <!-- Aspect --> <bean id="logAspect" class="org.arpit.java2blog.LoggingAspect" /> </beans> |
Create main class named SpringAOPMain to execute the application
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.arpit.java2blog; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringAOPMain { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml"); BusinessLogic businessLogic = (BusinessLogic) appContext.getBean("businessLogic"); businessLogic.getBusinessLogic(); } } |
When you run above program, you will get below output:
1 2 3 4 5 6 7 8 9 10 11 |
Jul 21, 2016 10:01:14 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@24174be7: startup date [Thu Jul 21 22:01:14 IST 2016]; root of context hierarchy Jul 21, 2016 10:01:14 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring-config.xml] loggingBeforeBusinessLogic() is running! Before execution of method : getBusinessLogic ***************** In Business Logic method ***************** |
@After:
I am replacing @Before method in LoggingAspect.java with @After annotated method.This method will execute after execution of actual business logic, so LoggingAspect.java will look something like this.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package org.arpit.java2blog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.After; @Aspect public class LoggingAspect { @After("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingAfterBusinessLogic(JoinPoint joinPoint) { System.out.println("loggingAfterBusinessLogic() is running!"); System.out.println("After execution of method : " + joinPoint.getSignature().getName()); } } |
When you run SpringAOPMain.java again, you will get below output:
1 2 3 4 5 6 7 8 9 10 11 |
Jul 21, 2016 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu Jul 21 22:24:26 IST 2016]; root of context hierarchy Jul 21, 2016 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring-config.xml] ***************** In Business Logic method ***************** loggingAfterBusinessLogic() is running! After execution of method : getBusinessLogic |
As you can see in above output, loggingAfterBusinessLogic executed after getBusinessLogic method
@AfterReturning:
I am replacing @After with @AfterReturning in above LoggingAspect.java.This method will execute after execution of actual business logic but only if it successfully returns.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package org.arpit.java2blog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterReturning; @Aspect public class LoggingAspect { @AfterReturning("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingAfterBusinessLogic(JoinPoint joinPoint) { System.out.println("loggingAfterBusinessLogic() is running!"); System.out.println("After execution of method : " + joinPoint.getSignature().getName()); } } |
When you run SpringAOPMain.java again, you will get below output:
1 2 3 4 5 6 7 8 9 10 11 |
Jul 21, 2016 10:24:26 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@75783d33: startup date [Thu Jul 21 22:24:26 IST 2016]; root of context hierarchy Jul 21, 2016 10:24:26 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring-config.xml] ***************** In Business Logic method ***************** loggingAfterBusinessLogic() is running! After execution of method : getBusinessLogic |
@AfterThrowing:
Lets add one more method with @AfterThrowing annotation. It will execute if any exception occurs in getBusinessLogic method.
LoggingAspect.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package org.arpit.java2blog; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; @Aspect public class LoggingAspect { @AfterReturning("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingAfterBusinessLogic(JoinPoint joinPoint) { System.out.println("loggingAfterBusinessLogic() is running!"); System.out.println("After execution of method : " + joinPoint.getSignature().getName()); } @AfterThrowing("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingAfterBusinessLogicException(JoinPoint joinPoint) { System.out.println("Exception occurred in getBusinessLogic method"); } } |
Now throw RuntimeException from getBusinessLogic to test @AfterThrowing exception. BusinessLogic.java
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package org.arpit.java2blog; public class BusinessLogic { public void getBusinessLogic() { System.out.println("*****************"); System.out.println("In Business Logic method"); System.out.println("*****************"); throw new RuntimeException(); } } |
When you run SpringAOPMain.java , you will get below output:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
Jul 21, 2016 10:34:55 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu Jul 21 22:34:55 IST 2016]; root of context hierarchy Jul 21, 2016 10:34:55 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring-config.xml] ***************** In Business Logic method ***************** Exception occurred in getBusinessLogic method Exception in thread "main" java.lang.RuntimeException at org.arpit.java2blog.BusinessLogic.getBusinessLogic(BusinessLogic.java:9) at org.arpit.java2blog.BusinessLogic$$FastClassBySpringCGLIB$$3d288cb4.invoke() at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653) at org.arpit.java2blog.BusinessLogic$$EnhancerBySpringCGLIB$$1fbd989f.getBusinessLogic() at org.arpit.java2blog.SpringAOPMain.main(SpringAOPMain.java:10) |
As you can see loggingAfterBusinessLogicException got executed as there is exception in business logic.
@Around:
Method with @Around will get called before and after execution of business logic.
You need to call reference of ProceedingJoinPoint and call proceed method to execute actual business logic.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package org.arpit.java2blog; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; @Aspect public class LoggingAspect { @Around("execution(* org.arpit.java2blog.BusinessLogic.getBusinessLogic(..))") public void loggingAroundBusinessLogic(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("Before calling actual business logic"); // Before running actual business logicic joinPoint.proceed(); // business logic method get executed System.out.println("After calling actual business logic"); // After running actual business logic } } |
When you run SpringAOPMain.java , you will get below output:
1 2 3 4 5 6 7 8 9 10 11 |
Jul 21, 2016 11:04:10 PM org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@739474: startup date [Thu Jul 21 23:04:10 IST 2016]; root of context hierarchy Jul 21, 2016 11:04:10 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions INFO: Loading XML bean definitions from class path resource [spring-config.xml] Before calling actual business logic ***************** In Business Logic method ***************** After calling actual business logic |