Spring AOP – AspectJ Annotation Config Example

Lokesh Gupta

One of the key components of Spring is the Aspect-Oriented Programming (AOP) framework. While the Spring IoC container does not depend on AOP, meaning you do not need to use AOP if you don’t want to, AOP complements Spring IoC to provide a very capable middleware solution. Just like the key unit of modularity in OOP is the class, in AOP the unit of modularity is the aspect. Aspects enable the modularization of concerns (you can read as crosscutting concerns as well) such as transaction management that cut across multiple types and objects.

AspectJ has grown into a complete and popular AOP framework, Spring supports the use of POJO aspects written with AspectJ annotations in its AOP framework. Since AspectJ annotations are supported by more and more AOP frameworks, your AspectJ-style aspects are more likely to be reused in other AOP frameworks that support AspectJ.

Unfortunately, AOP terminology is not very intuitive so I will start with creating an example application and then relate the terms with usage in example.

Spring AOP + AspectJ Example

Before writing any code, you will need to import Spring AOP dependencies into your project.

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>4.1.4.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>4.1.4.RELEASE</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>

In this example, I am taking a very basic implementation of EmployeeManager class having some set of methods which should basically select/modify EmployeeDTO object into database.

EmployeeDTO.java

public class EmployeeDTO {

	private Integer id;
	private String firstName;
	private String lastName;

	//Setters and Getters
}

EmployeeManager.java

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

@Component
public class EmployeeManager 
{
	public EmployeeDTO getEmployeeById(Integer employeeId) {
		System.out.println("Method getEmployeeById() called");
		return new EmployeeDTO();
	}

	public List<EmployeeDTO> getAllEmployee() {
		System.out.println("Method getAllEmployee() called");
		return new ArrayList<EmployeeDTO>();
	}

	public void createEmployee(EmployeeDTO employee) {
		System.out.println("Method createEmployee() called");
	}

	public void deleteEmployee(Integer employeeId) {
		System.out.println("Method deleteEmployee() called");
	}

	public void updateEmployee(EmployeeDTO employee) {
		System.out.println("Method updateEmployee() called");
	}
}

Then I have created a logging aspect which will record which method got executed.

EmployeeCRUDAspect.java

@Aspect
public class EmployeeCRUDAspect {
	
	@Before("execution(* EmployeeManager.getEmployeeById(..))")
	public void logBeforeV1(JoinPoint joinPoint) 
	{
		System.out.println("EmployeeCRUDAspect.logBeforeV1() : " + joinPoint.getSignature().getName());
	}
	
	@Before("execution(* EmployeeManager.*(..))")
	public void logBeforeV2(JoinPoint joinPoint) 
	{
		System.out.println("EmployeeCRUDAspect.logBeforeV2() : " + joinPoint.getSignature().getName());
	}
	
	@After("execution(* EmployeeManager.getEmployeeById(..))")
	public void logAfterV1(JoinPoint joinPoint) 
	{
		System.out.println("EmployeeCRUDAspect.logAfterV1() : " + joinPoint.getSignature().getName());
	}
	
	@After("execution(* EmployeeManager.*(..))")
	public void logAfterV2(JoinPoint joinPoint) 
	{
		System.out.println("EmployeeCRUDAspect.logAfterV2() : " + joinPoint.getSignature().getName());
	}
}

The applicationContext.xml file has below configuration to enable AOP and IoC container using annotation configuration.

<aop:aspectj-autoproxy />

<context:component-scan base-package="com.howtodoinjava.demo.aop" />

<bean id="loggingAspect" class="com.howtodoinjava.demo.aop.EmployeeCRUDAspect" />

Now test the AOP configuration and other stuff.

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestAOP
{
	@SuppressWarnings("resource")
	public static void main(String[] args) {

		ApplicationContext context = new ClassPathXmlApplicationContext("com/howtodoinjava/demo/aop/applicationContext.xml");
		EmployeeManager manager = context.getBean(EmployeeManager.class);

		manager.getEmployeeById(1);
		manager.createEmployee(new EmployeeDTO());
	}
}

Output:

EmployeeCRUDAspect.logBeforeV1() : getEmployeeById
EmployeeCRUDAspect.logBeforeV2() : getEmployeeById
Method getEmployeeById() called
EmployeeCRUDAspect.logAfterV1() : getEmployeeById
EmployeeCRUDAspect.logAfterV2() : getEmployeeById

EmployeeCRUDAspect.logBeforeV2() : createEmployee
Method createEmployee() called
EmployeeCRUDAspect.logAfterV2() : createEmployee

Great, AOP is configured successfully. Now move on to learn AOP terminology.

AOP Key Terms

Let us now define some central AOP concepts and terminology and relate with above example.

spring-aop-diagram

1) Aspect : a modularization of a concern that cuts across multiple classes. Transaction management is a good example of a crosscutting concern in enterprise Java applications.

In our example, we have created a logging aspect. To create an aspect, you need to apply @Aspect annotation on your aspect class and register it in applicationContext.xml file.

@Aspect
public class EmployeeCRUDAspect {
	...
}

This is how you register your aspect into context.

<bean id="loggingAspect" class="com.howtodoinjava.demo.aop.EmployeeCRUDAspect" />

Remember to add AOP support first into your context with “<aop:aspectj-autoproxy />“.

2) Join point : a point during the execution of a program, such as the execution of a method or the handling of an exception. In Spring AOP, a join point always represents a method execution.

In our example, all the methods defined inside EmployeeManager are joint points.

3) Advice : action taken by an aspect at a particular join point. Different types of advice include “around,” “before” and “after” advice. Many AOP frameworks, including Spring, model an advice as an interceptor, maintaining a chain of interceptors around the join point.

In our example, all logBefore() and logAfter() methods are advices.

4) Pointcut : a predicate that matches join points. Advice is associated with a pointcut expression and runs at any join point matched by the pointcut (for example, the execution of a method with a certain name). The concept of join points as matched by pointcut expressions is central to AOP, and Spring uses the AspectJ pointcut expression language by default.

In our example, the expressions passed in @Before and @After annotations (i.e. “execution(* EmployeeManager.getEmployeeById(..))“) are pointcuts.

5) Introduction : declaring additional methods or fields on behalf of a type. Spring AOP allows you to introduce new interfaces (and a corresponding implementation) to any advised object. For example, you could use an introduction to make a bean implement an IsModified interface, to simplify caching.

I will create a separate example for this.

6) Target object : object being advised by one or more aspects. Also referred to as the advised object. Since Spring AOP is implemented using runtime proxies, this object will always be a proxied object.

In our example, EmployeeManager is advised object hence it is the target object.

7) AOP proxy : an object created by the AOP framework in order to implement the aspect contracts (advise method executions and so on). In the Spring Framework, an AOP proxy will be a JDK dynamic proxy or a CGLIB proxy.

In our example, a proxy object is created when we ask the bean reference for EmployeeManager class. You can see the proxied class in below image, which is screen shot of debugger in runtime.

spring-aop-proxy-object

So we are good now and can relate the key terms of spring AOP with actual pieces of codes. Now moving further, let’s list down types of advices which are available for use in spring AOP.

  1. Before advice : Advice that executes before a join point, but which does not have the ability to prevent execution flow proceeding to the join point (unless it throws an exception). To use this advice, use @Before annotation as used in our example above.
  2. After returning advice : Advice to be executed after a join point completes normally: for example, if a method returns without throwing an exception. To use this advice, use @AfterReturning annotation.
  3. After throwing advice : Advice to be executed if a method exits by throwing an exception. To use this advice, use @AfterThrowing annotation.
  4. After advice : Advice to be executed regardless of the means by which a join point exits (normal or exceptional return). To use this advice, use @After annotation as used in our example above.
  5. Around advice : Advice that surrounds a join point such as a method invocation. This is the most powerful kind of advice. To use this advice, use @Around annotation.

Around advice can perform custom behavior before and after the method invocation. It is also responsible for choosing whether to proceed to the join point or to shortcut the advised method execution by returning its own return value or throwing an exception. An around advice can be written as below.

@Around("execution(* EmployeeManager.getEmployeeById(..))")
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable 
{
	System.out.println("Write code for before advise");
	
	joinPoint.proceed(); //continue to called method i.e. EmployeeManager.getEmployeeById()
	
	System.out.println("Write code for after advise");
}

That’s all for this introductory tutorial. I will post more tutorials with more detailed information on spring aspectj aop concepts.

Happy Learning !!

Reference : Spring Docs

Comments

Subscribe
Notify of
guest

4 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.