Spring AOP Example – Advice
Using AspectJ is more flexible and powerful, please refer to this tutorial – Using AspectJ annotation in Spring AOP.
Spring AOP (Aspect-oriented programming) framework is used to modularize cross-cutting concerns in aspects. Put it simple, it’s just an interceptor to intercept some processes, for example, when a method is execute, Spring AOP can hijack the executing method, and add extra functionality before or after the method execution.
In Spring AOP, 4 type of advices are supported :
- Before advice – Run before the method execution
- After returning advice – Run after the method returns a result
- After throwing advice – Run after the method throws an exception
- Around advice – Run around the method execution, combine all three advices above.
Following example show you how Spring AOP advice works.
Simple Spring example
Create a simple customer service class with few print methods for demonstration later.
package com.mkyong.customer.services; public class CustomerService { private String name; private String url; public void setName(String name) { this.name = name; } public void setUrl(String url) { this.url = url; } public void printName() { System.out.println("Customer name : " + this.name); } public void printURL() { System.out.println("Customer website : " + this.url); } public void printThrowException() { throw new IllegalArgumentException(); } }
File : Spring-Customer.xml – A bean configuration file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.mkyong.com" /> </bean> </beans>
Run it
package com.mkyong.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mkyong.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerService"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
Output
************************* Customer name : Yong Mook Kim ************************* Customer website : http://www.mkyong.com *************************
A simple Spring project to DI a bean and output some Strings.
Spring AOP Advices
Now, attach Spring AOP advices to above customer service.
1. Before advice
It will execute before the method execution. Create a class which implements MethodBeforeAdvice interface.
package com.mkyong.aop; import java.lang.reflect.Method; import org.springframework.aop.MethodBeforeAdvice; public class HijackBeforeMethod implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackBeforeMethod : Before method hijacked!"); } }
In bean configuration file (Spring-Customer.xml), create a bean for HijackBeforeMethod class , and a new proxy object named ‘customerServiceProxy‘.
- ‘target’ – Define which bean you want to hijack.
- ‘interceptorNames’ – Define which class (advice) you want to apply on this proxy /target object.
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.mkyong.com" /> </bean> <bean id="hijackBeforeMethodBean" class="com.mkyong.aop.HijackBeforeMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackBeforeMethodBean</value> </list> </property> </bean> </beans>
To use Spring proxy, you need to add CGLIB2 library. Add below in Maven pom.xml file.
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
Run it again, now you get the new customerServiceProxybean instead of the original customerService bean.
package com.mkyong.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mkyong.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext.getBean("customerServiceProxy"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
Output
************************* HijackBeforeMethod : Before method hijacked! Customer name : Yong Mook Kim ************************* HijackBeforeMethod : Before method hijacked! Customer website : http://www.mkyong.com ************************* HijackBeforeMethod : Before method hijacked!
It will run the HijackBeforeMethod’s before() method, before every customerService’s methods are execute.
2. After returning advice
It will execute after the method is returned a result. Create a class which implements AfterReturningAdvice interface.
package com.mkyong.aop; import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class HijackAfterMethod implements AfterReturningAdvice { @Override public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("HijackAfterMethod : After method hijacked!"); } }
Bean configuration file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.mkyong.com" /> </bean> <bean id="hijackAfterMethodBean" class="com.mkyong.aop.HijackAfterMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackAfterMethodBean</value> </list> </property> </bean> </beans>
Run it again, Output
************************* Customer name : Yong Mook Kim HijackAfterMethod : After method hijacked! ************************* Customer website : http://www.mkyong.com HijackAfterMethod : After method hijacked! *************************
It will run the HijackAfterMethod’s afterReturning() method, after every customerService’s methods that are returned result.
3. After throwing advice
It will execute after the method throws an exception. Create a class which implements ThrowsAdvice interface, and create a afterThrowing method to hijack the IllegalArgumentException exception.
package com.mkyong.aop; import org.springframework.aop.ThrowsAdvice; public class HijackThrowException implements ThrowsAdvice { public void afterThrowing(IllegalArgumentException e) throws Throwable { System.out.println("HijackThrowException : Throw exception hijacked!"); } }
Bean configuration file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.mkyong.com" /> </bean> <bean id="hijackThrowExceptionBean" class="com.mkyong.aop.HijackThrowException" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackThrowExceptionBean</value> </list> </property> </bean> </beans>
Run it again, output
************************* Customer name : Yong Mook Kim ************************* Customer website : http://www.mkyong.com ************************* HijackThrowException : Throw exception hijacked!
It will run the HijackThrowException’s afterThrowing() method, if customerService’s methods throw an exception.
4. Around advice
It combines all three advices above, and execute during method execution. Create a class which implements MethodInterceptor interface. You have to call the “methodInvocation.proceed();” to proceed on the original method execution, else the original method will not execute.
package com.mkyong.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); // same with MethodBeforeAdvice System.out.println("HijackAroundMethod : Before method hijacked!"); try { // proceed to original method call Object result = methodInvocation.proceed(); // same with AfterReturningAdvice System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { // same with ThrowsAdvice System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
Bean configuration file
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <bean id="customerService" class="com.mkyong.customer.services.CustomerService"> <property name="name" value="Yong Mook Kim" /> <property name="url" value="http://www.mkyong.com" /> </bean> <bean id="hijackAroundMethodBean" class="com.mkyong.aop.HijackAroundMethod" /> <bean id="customerServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="customerService" /> <property name="interceptorNames"> <list> <value>hijackAroundMethodBean</value> </list> </property> </bean> </beans>
Run it again, output
************************* Method name : printName Method arguments : [] HijackAroundMethod : Before method hijacked! Customer name : Yong Mook Kim HijackAroundMethod : Before after hijacked! ************************* Method name : printURL Method arguments : [] HijackAroundMethod : Before method hijacked! Customer website : http://www.mkyong.com HijackAroundMethod : Before after hijacked! ************************* Method name : printThrowException Method arguments : [] HijackAroundMethod : Before method hijacked! HijackAroundMethod : Throw exception hijacked!
It will run the HijackAroundMethod’s invoke()method, after every customerService’s method execution.
Conclusion
Most of the Spring developers are just implements the ‘Around advice ‘, since it can apply all the advice type, but a better practice should choose the most suitable advice type to satisfy the requirements.
In this example, all the methods in a customer service class are intercepted (advice) automatically. But for most cases, you may need to use Pointcut and Advisor to intercept a method via it’s method name.

The most concise and simplest AOP examples to be found on the web. Thanks!
One minor update: the ThrowsAdvice interface seems to have become no-op in Spring 2.5.5:
// Compiled from ThrowsAdvice.java (version 1.4 : 48.0, no super bit)
public abstract interface org.springframework.aop.ThrowsAdvice extends org.springframework.aop.AfterAdvice {
}
Really helpfull for beginners
thanks a lot
Really superb article for beginners like me. It is simply crystal clear and very meaningful. Thanks.
Great work
A nice explanation
Really helpful for Beginners.
Thanks a lot..
Very nice article.
Its Great. Good article.
But I tried the same but it is not taking beforemethodadvice… I added cglib jar file in build path.. But only thing is @override annotation in HijackBeforeAdvice is throwing me compilation error.. If I remove that, compilation error goes off but NOT RUNNING the HijackBeforeMethod’s before() method.
Can anyone please help me in this regard…I get simple output not the advice output..
Pleaazzzzz
which JVM version are you using? it should be 1.5 or above.
Its Great. Good article.
But I tried the same but it is not taking beforemethodadvice… I added cglib jar file in build path.. But only thing is @override annotation in HijackBeforeAdvice is throwing me compilation error.. If I remove that, compilation error goes off but NOT RUNNING the HijackBeforeMethod’s before() method.
Can anyone please help me in this regard…I get simple output not the advice output..
Pleaazzzzz
I added aopalliance 1.0 jar to my build path and this error went away
Nicely described.. carry on…
really helpful practical guide for beginners. thx lot!
Gr8 !! Super !!
You Rock !!
This example has set the foundation for me. It’s so simple and that’s all I needed to get started in AOP. I can now start to look more in depth at AOP.
Fantastic work, keep it up.
Regards
Ravi
I’m using Spring 3.1.2 and all my controllers are annotation driven. My spring context xml will not have any beans defines in that. How to achieve AOP in that case. i.e., is it possible to achieve AOP through annotations(not AspectJ though). Is it possible? If so, please let me know.
Hi. Do you find the answer on your question?
Hi,
The example is nice. I am yet to read in depth about AOP but am wondering whether the AOP can be selective on methods. For ex, assuming a class has n methods in it and I want certain things to take place only when x methods are invoked (x<n) and for the remaining (n-x) methods, nothing should happen (no AOP behavior). Please let me know if this is something which is possible?
Regards,
Ramakant
Yes , that is what mkYong mentionned in the end of the tutorial.refer to the next tutorial about Pointcut and Adviser
Great work! I am very much impressed…
This is very Helpfull to a beginer and best practise..
Thanks a lot ….
Hi,
My application context is:
This refers to my service bean which is declared using @Qualifier annotation in my controller class. Hence there is no bean entry with this id in application context.
No error is thrown but spring aop feature is not working.
Please suggest a workaround.
***** Updating my post below ******
In my web project, my service bean is declares as follows:
}
Clear and simple like all the other spring demo.
Dude seriously, thank you for your work :). I’m sure it’ll help a lot of beginer
Hi
I am getting a syntax error says
The hierarchy of the type Hijack BeforeMethod is inconsistent
at
public class HijackBeforeMethod implements MethodBeforeAdvice{.
what could be wrong??
its resolved adding AOP Alliance API 1.0.0
hi friend i feel same error that
I am getting a syntax error says
The hierarchy of the type Hijack BeforeMethod is inconsistent
at
public class HijackBeforeMethod implements MethodBeforeAdvice{.
how and where to add AOP Allianc API 1.0.0 and from where it download
step by step
plz answer me
http://ebr.springsource.com/repository/app/bundle/version/detail?name=com.springsource.org.aopalliance&version=1.0.0
This article totally opened my mind :)