You are here
Home > Spring Boot >

How to implement AOP in Spring Boot Application?

How to implement AOP in Spring Boot Application?If you are developing an application in Spring or using Spring Boot, you must have come across the word ‘AOP’. It stands for Aspect Oriented programming. Although AOP concept is a bit tough to understand, but undoubtedly it makes the developer’s life easy. You will feel it more than easy once you complete this topic ‘How to implement AOP in Spring Boot Application?’. In fact terminologies used in AOP concept by definition are very close to each other that makes it a bit tricky to understand effortlessly. However, we will understand all of them with suitable examples respectively.

While developing an application you might have observed that there are certain lines of code which appear in every class unknowingly. What will happen if we keep those repetitive lines of code in a separate class? On doing so, we will have a better readability of the code. Also, we can use them whenever they are required to be referenced, so we will have a better code reusability.

Now you might have a question in your mind: ‘What are these repetitive lines of code?’. In Simple terms the lines of code which we write to implement Logging, Security, Transaction Management, Data Transfer etc. We also call them ‘Cross-Cutting Concerns’. Furthermore, let’s talk about our topic ‘How to implement AOP in Spring Boot Application?’ step by step as a whole.

Table of Contents

What Can You Expect from This Article?

Once you finish reading this article, you will be able to answer:

1) What is an Aspect Oriented Programming?

2) What is the importance and benefits of implementing AOP in a Spring Boot Application?

3) What is a cross-cutting concern and How is it related to AOP concept?

4) What are various terminologies used in AOP like Advice, Pointcut, JoinPoint, Target, Proxy, Viewing etc.?

5) What are different ways to implement AOP in a Spring Application?

6) What is AspectJ all about?

7) How many types are advices are there?

8) Also, What is the difference between After, After Returning and After Throwing Advices?

9) Where to use various annotations like @EnableAspectJAutoProxy, @Aspect, @Pointcut, @Before, @After, @AfterReturning, @AfterThrowing, @Around etc.?

10) Additionally, Examples of Pointcut expressions, including brainstorming exercise.

11) How does a Pointcut expression select a method having a specific annotation?

12) Last but not the Least, ‘How To Implement AOP In Spring Boot Application?’.

What is Cross-Cutting Concern?

Cross-Cutting Concern is nothing, but the part of our program that affects other parts of the program in our application. As the name suggests, it is a concern which has influence in the entire application. In other words, it is applicable throughout the application. Generally, we incorporate these concerns in almost every layer of an enterprise application. For example Logging, Security, Transaction Management, Data Transfer, Error Handling, Performance Monitoring, Caching, Custom Business Rules etc. In fact It represents additional features in an application. Consequently Cross-cutting is the process of separating out the additional feature code from the primary business logic code.

What is AOP (Aspect Oriented Programming)?

Aspect-oriented programming (AOP) is a programming paradigm that focuses on increasing modularity with the help of separation of cross-cutting concerns. However It makes it possible by adding additional behavior to existing code (we also call it an advice) without modifying the code itself. Instead, it does so by separately specifying which code is modified via a “pointcut” specification, such as “log all function calls when the function’s name begins with ‘get'”. In fact this allows behaviors that doesn’t come under the business logic (such as logging) to be added to a program without messing up the code. AOP forms a foundation for aspect-oriented software development.

As aforementioned AOP helps us in increasing modularity, It follows Object-oriented Programming(OOP) in the feeling that it also delivers modularity. But the difference is that in AOP unit of modularity becomes Aspect in place of a Class.

What is Spring AOP?

When we apply Aspect Oriented programming in a Spring Application, we call this concept as Spring AOP. Primarily in Spring AOP we use this concept in transaction management, logging, security, exception handling to modularize the concerns.

Spring AOP is a key feature of the Spring Framework that allows us to separate cross-cutting concerns from the core business logic of our application. Spring AOP provides a way to modularize these concerns, making our code more maintainable and improving the separation of concerns in our application.

What is an Aspect in AOP?

Consider we have an enterprise application code where we divide all code in two major parts. One part which has application’s primary business logic in such a way that without this part application’s functionality will not work. We call this part as core concern(business logic). While cross-cutting concern is the other remaining part that incorporates additional features such as Logging, Security, Exception Handling etc. Here, programmatically Aspects are the classes that we write separately to implement additional features.

What is an advice?

An Advice is the actual implementation of an Aspect. Programmatically, advices are the methods that we write inside an Aspect class to implement the additional features.

What is a Pointcut?

Pointcut is an expression that tells us which business logic method needs advice. However, one point is to notice that Pointcut never tells us what advice to apply. But in it’s expression, it only specifies the list of business logic methods where we need to apply advice. In brief it’s a kind of business logic method selector as a whole. Equally important, a Pointcut expression allows only two symbols : *(star), .(dot)

What is a JoinPoint?

JoinPoint combines the Pointcut with advices. It connects the selected business logic methods with the required advices.

What is a Target?

Target is a plain business class without any advice. This is our target which needs advice.

What is a Proxy?

Proxy is a final output of viewing. In fact a proxy object gets created when a business method mixed with advice is called.

What is Viewing?

In brief Viewing is the process of mixing required advices with business logic methods.

What are the different ways to implement AOP in a Spring application?

Generally there are two ways to implement AOP in a Spring Application.

1) Using XML Based Configuration: This method uses XMLs to implement AOP concepts. However now-a-days very less or negligible people use this style.
2) Using AspectJ Annotations: Here in this method, we completely use annotations. Moreover  AspectJ is an aspect-oriented programming (AOP) library as extension created at PARC for the Java programming language. It is available in Eclipse Foundation open-source projects, both stand-alone and integrated into Eclipse. AspectJ has become very popular and widely used effective standard for AOP by highlighting simplicity and usability among developers. It uses Java-like syntax, and included IDE integrations for displaying cross-cutting structures.

How many types of Advice are there?

We have five types of Advice as given below. Types of Advice are on the basis of all possibilities in execution of a business method.

Before Advice 

Before Advice executes before the execution of business method. Once Advice execution completes method execution will take place automatically.

After Advice 

After Advice executes after the execution of business method. Once method execution completes advice execution will take place automatically.

Around Advice 

Around Advice executes in two parts. Some part executes before the execution of business method, whereas other part executes after the execution of business method.

After Returning Advice 

It executes after the execution of business method, but only if method executes successfully.

After Throwing Advice

It executes after the execution of business method, but only if method fails to execute successfully.

♦ Although we can have any number of either same type of advice or of different type connected to a single business method.

What is the difference among After, After Returning & After Throwing Advices?

After Advice mandatorily executes after the execution of business method, but other two advices may or may not execute after the execution of business method. After Returning Advice will execute only on successful execution of business method, whereas After Throwing Advice will execute only on failure in execution of business method.

What are different annotations used in AOP ?

@Aspect

We apply @Aspect on top of the class to represent that this class is an Aspect. For example, below InvoiceAspect class represents an Aspect.

@Aspect
public class InvoiceAspect { }

@Pointcut

@Pointcut is applied on top of a method in the Aspect class. It has an expression in the bracket to select the business methods accordingly. Remember that it will only select the business methods which need advice, but never talks about which advice. For example, below p1() method represents a pointcut.

@Pointcut("execution(public void com.dev.spring.aop.service.InvoiceBusinessService.saveInvoice())")
public void p1() { }

Further below Annotations are the types of Advices. An advice must be annotated with any one type of the advice.
Every Advice Type Annotation must describe related pointcut information in the bracket.

@Before

Method annotated with @Before represents the Before Advice and it will execute before the execution of business method. For example, below method represents Before Advice with Pointcut as p1().

@Before("p1()")
public void beginTransaction() {
      System.out.println("Transaction begins !");
}

@After 

Method annotated with @After represents the After Advice and it will execute after the execution of business method. For example, below method represents After Advice with Pointcut as p1().

@After("p1()")
public void completeTransaction() {
      System.out.println("Transaction completes !");
}

@AfterReturning

Method annotated with @AfterReturning represents the After Returning Advice and it will execute after the execution of business method but only if method executes successfully. For example, below code demonstrates the concept of After Returning Advice with Pointcut as p1().

@AfterReturning("p1()")
public void commitTransaction() {
      System.out.println("Transaction committed !");
}

@AfterThrowing

Method annotated with @AfterThrowing represents the After Throwing Advice and it will execute after the execution of business method, but only if method fails to execute successfully. For example, below method represents After Throwing Advice with Pointcut as p1().

@AfterThrowing("p1()")
public void rollbackTransaction() {
      System.out.println("Transaction rolled back !");
}

@Around

Method annotated with @Around represents the Around Advice. It executes in two parts. Some part executes before the execution of business method, whereas other part executes after the execution of business method. For example, below method represents Around Advice with Pointcut as p4().

@Around("p4()")
public void testAroundAdvice(ProceedingJoinPoint pj) throws Throwable {
       System.out.println("Executing Before part of business method");
       pj.proceed(); // this code will call business method
       System.out.println("Executing After part of business method");
}

Examples of Pointcut Expressions 

On the whole a Pointcut expression allows only two symbols which are *(star), .(dot). Therefore, we will discuss different combinations of them in our examples. Equally important, the Syntax for Pointcut Expression is as below:

Specifier ReturnType Package.ClassName.MethodName(ParameterTypes)

( ) => indicates zero parameter or without parameter
(..) => indicates any number or type of parameters

Which methods will be candidate to get advices in the expression  :

Ex#1) public Integer com.dev.dao.InvoiceDao.saveInvoice(Invoice)
saveInvoice() method with a Invoice Type parameter inside InvoiceDao class

Ex#2) public Integer com.dev.dao.InvoiceDao.saveInvoice( )
saveInvoice() method with no parameter inside InvoiceDao class

Ex#3) public Integer com.dev.dao.InvoiceDao.*( )
Any method inside InvoiceDao class that returns integer

Ex#4) public * com.dev.dao.InvoiceDao.*( )
Any method inside InvoiceDao

Ex#5) public * com.dev.dao.InvoiceDao.*(..)
Any method with zero or more parameters inside InvoiceDao

Ex#6) public * com.dev.dao.*.*(..)
All classes which are inside com.dev.dao package and their respective methods

Brainstorming Exercise to revise all types of Pointcut Expressions

Suppose we have below four methods under package com.dev.invoice.controller

M1) public Integer saveInvoice(Invoice inv){….}
M2) public void deleteInvoice(Integer id){….}
M3) public void updateInvoice(Invoice inv){….}
M4) public Invoice getInvoice(Integer id){….}

Q#1) Select the methods(given above) which are candidate for Pointcut Expression : public   * *( )
Ans.  No methods will satisfy the given expression as each method has one parameter.

Q#2) Select the methods which are candidate for Pointcut Expression : public void *(..)
Ans.  M2 & M3 methods will satisfy the given expression as (..) represents any number or type of parameters.

Q#3) Select the methods which are candidate for Pointcut Expression : public * *(Invoice)
Ans.  M1 & M3 methods will satisfy the given expression as these methods have Invoice type parameter.

How to implement AOP in Spring Boot Application?

As we have already learnt all the terminologies used in AOP concept. Finally, it’s time to proceed with ‘How to implement AOP in Spring Boot Application?’. Furthermore, in this section we will learn ‘How to implement AOP in Spring Boot Application?’ programmatically by writing Aspects, Pointcuts & Advices step by step accordingly.

Tools & Technologies used in this example project

♦ STS (Spring Tool Suite) : Version-> 4.7.1.RELEASE
♦ JDK8 or later versions (Extremely tested on JDK8, JDK11 and JDK15)

Let’s follow below steps to develop a small example and then apply AOP concept into it accordingly.

Step#1 : Create a Spring Boot Starter Project in STS(Spring Tool Suite)

While creating Starter Project don’t select any starter project dependencies as we need to add an external dependency in pom.xml to get AOP features. Even If you don’t know how to create Spring Boot Starter Project, Kindly visit Internal Link.

Step#2 : Update pom.xml file 

Further to get features of AOP we need to add below dependency in pom.xml.

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

Step#2 : Apply @EnableAspectJAutoProxy on Spring Boot Project’s main class 

You have to apply @EnableAspectJAutoProxy on top of your Spring Boot Project’s main class as below.

SpringBoot2AopApplication.java
package com.dev.spring.aop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@SpringBootApplication
@EnableAspectJAutoProxy
public class SpringBoot2AopApplication {

public static void main(String[] args) {
SpringApplication.run(SpringBoot2AopApplication.class, args);
}
}

Step#3 : Create one Business service class

Create one class as InvoiceBusinessService.java which will act as a business service class with business methods. However methods in this class will be candidate to get advice. Consequently pointcut expression will select methods from this class itself. Of course these are dummy methods just to understand AOP concepts.

InvoiceBusinessService.java
package com.dev.spring.aop.service;

import java.util.Random;

import org.springframework.stereotype.Component;


@Component
public class InvoiceBusinessService {

public void saveInvoice() {
System.out.println("From saveInvoice()");
if(new Random().nextInt(15)<=10) {
throw new RuntimeException("Exception occured");
}
}

public String helloInvoice() {
return "FROM helloInvoice()";
}

public void testMethodforAroundAdvice() {
System.out.println("Business Method is getting Executed !");
}

}

Step#4 : Create a Runner class to call & execute business methods

Next we will write one Runner class as InvoiceRunner.java that will call our business methods to test how advices are working with them.

InvoiceRunner.java
package com.dev.spring.aop;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import com.dev.spring.aop.service.InvoiceBusinessService;

@Component
public class InvoiceRunner implements CommandLineRunner {

@Autowired
private InvoiceBusinessService service;

@Override
public void run(String... args) throws Exception {

service.helloInvoice();
service.testMethodforAroundAdvice();
service.saveInvoice();

}

}

Step#5 : Create one Aspect class and it’s methods

Create one Aspect class as InvoiceAspect.java. Further, in this class define pointcuts & advices as below.

InvoiceAspect.java
package com.dev.spring.aop.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class InvoiceAspect {

@Pointcut("execution(public void com.dev.spring.aop.service.InvoiceBusinessService.saveInvoice())")
public void p1() {

}

@Pointcut("execution(public String com.dev.spring.aop.service.InvoiceBusinessService.helloInvoice())")
public void p2() {

}


@Pointcut("execution(* com.dev.spring.aop.service.InvoiceBusinessService.testMethodforAroundAdvice())")
public void p4() {

}

@Before("p1()")
public void beginTransaction() {
System.out.println("Transaction begins !");
}

@After("p1()")
public void completeTransaction() {
System.out.println("Transaction completes !");
}

@AfterReturning("p1()")
public void commitTransaction() {
System.out.println("Transaction committed !");
}

@AfterThrowing("p1()")
public void rollbackTransaction() {
System.out.println("Transaction rolled back !");
}

@AfterReturning(value="p2()", returning = "obj")
public void getAdviceReturnValue(Object obj) {
System.out.println("Returning Value is : "+obj);
}

@AfterThrowing(value="p1()", throwing = "th")
public void rollbackTransactionGetMessage(Throwable th) {
System.out.println("Transaction rolled back ! Message from method : "+th);
}


@Around("p4()")
public void testAroundAdvice(ProceedingJoinPoint pj) throws Throwable {

System.out.println("Executing Before part of business method");

pj.proceed(); // this code will call business method

System.out.println("Executing After part of business method");
}
}

Step#5 : Testing the AOP Concepts

Start the application : Right click on the project, then select “Run As’ >> ‘Spring Boot App’.

output :

Finally you will see the output something like below.

Output
Returning Value is : FROM helloInvoice()
Executing Before part of business method
Business Method is getting Executed !
Executing After part of business method
Transaction begins !
From saveInvoice()
Transaction rolled back ! Message from method : java.lang.RuntimeException: Exception occured
Transaction rolled back !
Transaction completes !
2021-01-08 21:32:57.674 INFO 23724 --- [ main] ConditionEvaluationReportLoggingListener :

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2021-01-08 21:32:57.685 ERROR 23724 --- [ main] o.s.boot.SpringApplication : Application run failed

java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:807) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:788) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) ~[spring-boot-2.4.1.jar:2.4.1]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) ~[spring-boot-2.4.1.jar:2.4.1]
at com.dev.spring.aop.SpringBoot2AopApplication.main(SpringBoot2AopApplication.java:12) ~[classes/:na]
Caused by: java.lang.RuntimeException: Exception occured
at com.dev.spring.aop.service.InvoiceBusinessService.saveInvoice(InvoiceBusinessService.java:15) ~[classes/:na]
at com.dev.spring.aop.service.InvoiceBusinessService$$FastClassBySpringCGLIB$$98eaa008.invoke(<generated>) ~[classes/:na]

How does a Pointcut expression selects a method having a specific annotation?

Moreover a Pointcut can also select a business method having a specific annotation. To illustrate this we will create one annotation. Further, we will apply this annotation to a business method. Then write a pointcut expression to select this method to apply advice into it. At the last step we will create an advice to connect with annotated business method accordingly. Finally, call this business method from our Runner class.

Step#1 : Create one custom annotation

TestAnnotation.java
package com.dev.spring.aop.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {

}

Step#2 : Write one business method and apply custom annotation

testMethodWithAnnotation()
@TestAnnotation
public void testMethodWithAnnotation() {
System.out.println("FROM testMethodWithAnnotation()");
}

Step#3 : Write one Pointcut and one Advice

Pointcut & Advice
@Pointcut("@annotation(com.dev.spring.aop.annotation.TestAnnotation)")
public void p3() {

}

@Before("p3()")
public void testAnnotatedMethod() {
System.out.println(" From testAnnotatedMethod()");
}

Step#4 : Update Runner class run() method

InvoiceRunner.java
@Component
public class InvoiceRunner implements CommandLineRunner {

@Autowired
private InvoiceBusinessService service;

@Override
public void run(String... args) throws Exception {

service.testMethodWithAnnotation();

}

}

Step#4 : Testing Advice on an Annotated method

Start the application : Right click on the project, then select “Run As’ >> ‘Spring Boot App’.

output :

Finally you will see the output something like below.

From testAnnotatedMethod()
FROM testMethodWithAnnotation()

You may also read: Other Tutorials & Implementations on Spring Boot.

Summary

After going through all the theoretical & examples part of ‘How to implement AOP in Spring Boot Application?’, finally, we are able to implement AOP concept in a Spring Boot project. Of course, In this article we have covered fundamental way of implementing AOP feature. Similarly, we expect from you to further extend these examples and implement them in your project accordingly. You can also check other details on implementing AOP in Spring  from spring.io. In addition, If there is any update in future, we will also update the article accordingly. Moreover, Feel free to provide your comments in below comments section.

2 thoughts on “How to implement AOP in Spring Boot Application?

Leave a Reply


Top