Main Tutorials

Spring AOP + AspectJ annotation example

In this tutorial, we show you how to integrate AspectJ annotation with Spring AOP framework. In simple, Spring AOP + AspectJ allow you to intercept method easily.

Common AspectJ annotations :

  1. @Before – Run before the method execution
  2. @After – Run after the method returned a result
  3. @AfterReturning – Run after the method returned a result, intercept the returned result as well.
  4. @AfterThrowing – Run after the method throws an exception
  5. @Around – Run around the method execution, combine all three advices above.
Note
For Spring AOP without AspectJ support, read this build-in Spring AOP examples.

1. Directory Structure

See directory structure of this example.

directory structure of this example

2. Project Dependencies

To enable AspectJ, you need aspectjrt.jar, aspectjweaver.jar and spring-aop.jar. See following Maven pom.xml file.

AspectJ supported since Spring 2.0
This example is using Spring 3, but the AspectJ features are supported since Spring 2.0.

File : pom.xml


<project ...>

	<properties>
		<spring.version>3.0.5.RELEASE</spring.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- Spring AOP + AspectJ -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.11</version>
		</dependency>
		
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.6.11</version>
		</dependency>
		
	</dependencies>
</project>

3. Spring Beans

Normal bean, with few methods, later intercept it via AspectJ annotation.


package com.mkyong.customer.bo;

public interface CustomerBo {

	void addCustomer();
	
	String addCustomerReturnValue();
	
	void addCustomerThrowException() throws Exception;
	
	void addCustomerAround(String name);
}

package com.mkyong.customer.bo.impl;

import com.mkyong.customer.bo.CustomerBo;

public class CustomerBoImpl implements CustomerBo {

	public void addCustomer(){
		System.out.println("addCustomer() is running ");
	}
	
	public String addCustomerReturnValue(){
		System.out.println("addCustomerReturnValue() is running ");
		return "abc";
	}
	
	public void addCustomerThrowException() throws Exception {
		System.out.println("addCustomerThrowException() is running ");
		throw new Exception("Generic Error");
	}
	
	public void addCustomerAround(String name){
		System.out.println("addCustomerAround() is running, args : " + name);
	}
}

4. Enable AspectJ

In Spring configuration file, put “<aop:aspectj-autoproxy />“, and define your Aspect (interceptor) and normal bean.

File : Spring-Customer.xml


<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="customerBo" class="com.mkyong.customer.bo.impl.CustomerBoImpl" />

	<!-- Aspect -->
	<bean id="logAspect" class="com.mkyong.aspect.LoggingAspect" />

</beans>

4. AspectJ @Before

In below example, the logBefore() method will be executed before the execution of customerBo interface, addCustomer() method.

Note
AspectJ “pointcuts” is used to declare which method is going to intercept, and you should refer to this Spring AOP pointcuts guide for full list of supported pointcuts expressions.

File : LoggingAspect.java


package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

	@Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
	public void logBefore(JoinPoint joinPoint) {

		System.out.println("logBefore() is running!");
		System.out.println("hijacked : " + joinPoint.getSignature().getName());
		System.out.println("******");
	}

}

Run it


	CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomer();

Output


logBefore() is running!
hijacked : addCustomer
******
addCustomer() is running 

5. AspectJ @After

In below example, the logAfter() method will be executed after the execution of customerBo interface, addCustomer() method.

File : LoggingAspect.java


package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {

	@After("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
	public void logAfter(JoinPoint joinPoint) {

		System.out.println("logAfter() is running!");
		System.out.println("hijacked : " + joinPoint.getSignature().getName());
		System.out.println("******");

	}

}

Run it


	CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomer();

Output


addCustomer() is running 
logAfter() is running!
hijacked : addCustomer
******

6. AspectJ @AfterReturning

In below example, the logAfterReturning() method will be executed after the execution of customerBo interface, addCustomerReturnValue() method. In addition, you can intercept the returned value with the “returning” attribute.

To intercept returned value, the value of the “returning” attribute (result) need to be same with the method parameter (result).

File : LoggingAspect.java


package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

   @AfterReturning(
      pointcut = "execution(* com.mkyong.customer.bo.CustomerBo.addCustomerReturnValue(..))",
      returning= "result")
   public void logAfterReturning(JoinPoint joinPoint, Object result) {

	System.out.println("logAfterReturning() is running!");
	System.out.println("hijacked : " + joinPoint.getSignature().getName());
	System.out.println("Method returned value is : " + result);
	System.out.println("******");

   }

}

Run it


	CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomerReturnValue();

Output


addCustomerReturnValue() is running 
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
******

7. AspectJ @AfterReturning

In below example, the logAfterThrowing() method will be executed if the customerBo interface, addCustomerThrowException() method is throwing an exception.

File : LoggingAspect.java


package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class LoggingAspect {

   @AfterThrowing(
      pointcut = "execution(* com.mkyong.customer.bo.CustomerBo.addCustomerThrowException(..))",
      throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {

	System.out.println("logAfterThrowing() is running!");
	System.out.println("hijacked : " + joinPoint.getSignature().getName());
	System.out.println("Exception : " + error);
	System.out.println("******");

    }
}

Run it


	CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomerThrowException();

Output


addCustomerThrowException() is running 
logAfterThrowing() is running!
hijacked : addCustomerThrowException
Exception : java.lang.Exception: Generic Error
******
Exception in thread "main" java.lang.Exception: Generic Error
	//...

8. AspectJ @Around

In below example, the logAround() method will be executed before the customerBo interface, addCustomerAround() method, and you have to define the “joinPoint.proceed();” to control when should the interceptor return the control to the original addCustomerAround() method.

File : LoggingAspect.java


package com.mkyong.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;

@Aspect
public class LoggingAspect {

   @Around("execution(* com.mkyong.customer.bo.CustomerBo.addCustomerAround(..))")
   public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

	System.out.println("logAround() is running!");
	System.out.println("hijacked method : " + joinPoint.getSignature().getName());
	System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));
		
	System.out.println("Around before is running!");
	joinPoint.proceed(); //continue on the intercepted method
	System.out.println("Around after is running!");
		
	System.out.println("******");

   }
	
}

Run it


	CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
	customer.addCustomerAround("mkyong");

Output


logAround() is running!
hijacked method : addCustomerAround
hijacked arguments : [mkyong]
Around before is running!
addCustomerAround() is running, args : mkyong
Around after is running!
******

Conclusion

It’s always recommended to apply the least power AsjectJ annotation. It’s rather long article about AspectJ in Spring. for further explanations and examples, please visit the reference links below.

Anti annotation or using JDK 1.4 ?
No worry, AspectJ supported XML configuration also, read this Spring AOP + AspectJ XML example.

Download Source Code

Download it – Spring3-AOP-AspectJ-Example.zip (8 KB)

References

  1. AspectJ programming guide
  2. Spring AOP + AspectJ reference

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
59 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
siddharth agarwal
6 years ago

There is typo AfterThrowing —> AfterReturning

Ron Kitay
10 years ago

An important note for @Around is missing here and that is that an @Around advice must also return the value from the call to joinPoint.proceed() – you should correct the sample or at least add a note about it

Disabled Dating Service
10 years ago

I do believe all of the ideas you’ve introduced for your post. They’re very convincing and can certainly work.

Still, the posts are too brief for beginners. May you please extend them a bit from next time?

Thanks for the post.

Van
3 years ago

Thanks! Very helpful!

Biraja Rout
3 years ago

Is it possible to apply the AOP concept in website(with spring mvc) means before any bean method, can we execute any aspect

Vinayak K
5 years ago

i called @before on controller but want to stop execution of controller if user is not logged-in and want to return something as response-body (json shows the status that USER NOT LOGGED-IN ) else normal controller execution??(work around i throw error(“USER NOT LOGGED-IN”)) but want permanent solution.

Raeesaa
6 years ago

I had a question. Is it possible to get method argument names in @Around advice?

Raeesaa
6 years ago
Reply to  Raeesaa

Using java 7

Raushan Kumar Singh
7 years ago

I need to log method calling methods ?? Any tutorial on LTW .

Raushan Kumar Singh
7 years ago

What is the best method to log chained method! ?? I don’t know MAVEN so please any solution through spring

Julien
7 years ago

7. AspectJ @AfterReturning has to be 7. AspectJ @AfterThrowing

Amrut
8 years ago

Hi,

My main package folder is com.base and it has multiple folders like aspect, dao, web/controller, domain, service etc
I want to apply this aspect for all the methods from all the classes under com.base folder.

My spring config (web-servlet.xml) has

I have created one logging aspect as below

@Aspect
public class LoggingAspect {
/** Following is the definition for a pointcut to select
* all the methods available. So advice will be called
* for all the methods.
*/

@Pointcut(“execution(* com.base.*.*(..))”)
private void selectAll(){System.out.println(“logBefore() is running!”);}

/**
* This is the method which I would like to execute
* before a selected method execution.
*/
@Before(“selectAll()”)
public void logBefore(JoinPoint joinPoint) {
MDC.put(“logFileName”, “AppLog”);
System.out.println(“logBefore() is running!”);
System.out.println(“hijacked : ” + joinPoint.getSignature().getName());
System.out.println(“******”);
MDC.remove(“logFileName”);
}
}

But when I run my application, I am not getting any message printed on console from this logger aspect.

Please help. Thanks in Advance.

Amrut

Jaydeep
4 years ago
Reply to  Amrut

The pattern for execution is as below:
@Pointcut(“execution(* com.base.*.*.*(..))”)
–Notice the extra * added in the pattern. Depending upon level of packages, you may need to give that..

Pavan
8 years ago

The 7th point.. Please make it @AfterThrowing..6th and 7th both has @AfterReturning, a typo mistake..

Dee One
8 years ago

do you have any idea how i can get the trace of the current running method? like i need to get the full text of the current method in a running program, not the name, signature etc.

Anuj Joshi
8 years ago

I am getting an exception as:

java.lang.IllegalArgumentException: Can not set com.fasterxml.jackson.databind.ObjectMapper field in.dao.whooshbox.BaseDao.mapper to com.sun.proxy.$Proxy30

at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)

at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)

at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)

at java.lang.reflect.Field.set(Field.java:764)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:551)

at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)

at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)

Could you please help me figure out the issue.

duqi
8 years ago

Hi? The 7 should be @AfterThrowing

Kishore
8 years ago

I have a question on enabling logging for different methods in classes of a module: Do I need to create bean object from context for each class intending to get logging. Is there any way I can enable logging for every method using aspectj without creating object through context. Also, incase of a method inside the same class. I would not need to create a object. I can simply call the method by name. How to enable logging for it?

Tarun Gupta
8 years ago

I have one service method which calls the Dao method to fetch the record from the database. When i deploy the web application it is working fine and fetching the records from database but the moment i apply the around advice(which just have the sysout statements) on the service method, it is returning the null value. When i enabled the debug logger level i have noticed the below behavior
1. As per the logs, the dao method successfully loads the records from database
2. The aspect is also applied on the service method

But I’m not sure, on applying aspect, why I’m getting the null value in controller from service? Can any one help me on this

Tarun Gupta
8 years ago
Reply to  Tarun Gupta

This is resolved now. Some how the @Aspect and @Component annotation was applied on the loggingAspect class, as soon as i removed @component annotation, it worked!

JoonHo
8 years ago

great tutorial.. 🙂
thank, Mkyoung!!

Achilles Ram
9 years ago

i need one help from you, that is can we have one post about @Configurable please,, please explain me at [email protected]

Mark
10 years ago

Please fix the section title on the page https://mkyong.com/spring3/spring-aop-aspectj-annotation-example/. The correct section title “7. AspectJ @AfterThrowing”

Marcello Zanelli
10 years ago

Great tutorial! 😀

vijay
10 years ago

Thanks for putting all this together.

I have a one question in spring transaction management AOP is used and following XML configuration is used to manage transaction.

I don’t see any pointcut (Before/after/AfterReturning/AfterThrowing/Around) like . Please help me out to understand that how this transaction advise executes.

Thanks

hzxlb910
10 years ago

good,thanks

Cristian Daniel Ortiz
10 years ago

Hi i am a completely newbie in AOP what if i need to to fill some fields in a class before call another method some flags (update,delete,save) i use beforeAdvice

@Before(“execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))”)
public void logBefore(JoinPoint joinPoint)
{

System.out.println(“logBefore() is running!”);
System.out.println(“hijacked : ” + joinPoint.getSignature().getName());
System.out.println(“******”);
}

and the method receives a parameter example

DAO.Student.update(Student studenToBeUpdated)

how can i access the Student to apply my flags befored saved??

Abhijit
10 years ago

There is very blog explain in very lucid manner to understand newbie
Keep it good work!
Thanks a lot 🙂

Ram
10 years ago

7. AspectJ @AfterReturning should be 7. AspectJ @AfterThrowing

Vinod Maladkar
10 years ago

Very good blog and nice example.

jagan
10 years ago

Hi Kyoung,

First of all, thanks a lot for publishing all this valuable information and aggregating on 1 web site. I visit your site frequently to clarify my knowledge. Now i have 1 question and the scenario is as follows:
org.abc.xyz.service.CounterService.activeCount()
and this service will be invoked from 2 execution paths:
1. org.abc.xyx.controllers.ABCController and
2. org.abc.xyz.controllers.XYZController

Now my question is can we have an aspect on activeCount for the execution path:- ABCController–>CounterService

thanks,
jagan

Look
11 years ago

Its such as you read my mind! You appear to know a
lot about this, such as you wrote the e-book in it or something.
I think that you simply can do with some percent to drive the message home a bit, but instead
of that, that is great blog. An excellent read. I’ll certainly be back.

Jay Khimani
11 years ago

Thanks for sharing this concise tutorial. It was a great help. One question. Is there a way to define an aspect which intercepts annotated fields? For e.g. If I’ve below class

package com.jak.sandbox.aspect;

public class MyClass {
     @MyAnnotation
     private String myField;

     public void doSomething() {
          System.out.println("Saving the world");
     }
}

Now is it possible to define an aspect which will intercept the the field

myField

and invoke pointcut?