Spring Boot + AOP + Before After Advice Example (2024)
In this tutorial, we'll see how to use aspectj @Before
and @After
annotation to handle cross-cutting problems.
Let's start developing Spring Boot application with AOP.
Project Structure
Maven Dependency
The spring-boot-starter-aop
dependency must be included when introducing AOP in
spring boot. Spring-aop
and aspectjweaver
dependencies are imported
into the application.
<?xml version="1.0"?>
<project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.techgeeknext</groupId>
<artifactId>SpringBoot-AOP-Before-After-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBoot-AOP-Before-After-Example</name>
<description>SpringBoot AOP Logging Example</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
</dependencies>
</project>
Take a look at our suggested posts:
Create Aspects
In spring boot, an aspect can be created using the @Aspect
annotation and
registered with a bean
container using the @Component
annotation.
We can create advices as needed within the aspect class. For example, the following class applies to
methods in all classes in the com.techgeeknext
package. The logger will get applied Before
and After every method call.
package com.techgeeknext.aop;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class BeforeAfterAspectExample {
private static final Logger LOGGER = LogManager.getLogger(BeforeAfterAspectExample.class);
@Before("execution(* com.techgeeknext..*(..)))")
public void logBeforeAllMethodCall(JoinPoint joinPoint) throws Throwable {
LOGGER.info("======TECHGEEKNEXT - Spring Boot AOP Before Advice Example ");
LOGGER.info("=====Started with method "
+ joinPoint.getSignature().getName()); // Method Name
}
@After("execution(* com.techgeeknext..*(..)))")
public void logAfterAllMethodCall(JoinPoint joinPoint) throws Throwable {
LOGGER.info("=====TECHGEEKNEXT - Spring Boot AOP After Advice Example ");
LOGGER.info("======Completed execution of method "
+ joinPoint.getSignature().getName()); // Method Name
}
}
Employee Service to test Advice
We'll create simple service so that we can test our AOP Advice.
package com.techgeeknext.service;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
public class EmployeeService
{
private static final Logger LOGGER = LogManager.getLogger(EmployeeService.class);
public Object getEmployeeById(Integer empId)
{
try {
Thread.sleep(new Random().nextInt(2000));
} catch (InterruptedException exception) {
LOGGER.error("Error occurred in business service : {}",exception.getMessage());
}
return empId;
}
}
Create test class to test the AOP Advice.
package com.techgeeknext;
import com.techgeeknext.service.EmployeeService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class LoggingAopSpringBootTest
{
@Autowired
private EmployeeService employeeService;
@Test
public void testGetEmployeeById() {
employeeService.getEmployeeById(123);
}
}
Test the Spring Logging AOP
Now, execute mvn spring-boot run
command to start spring boot application.
Once application has started, you can notice test class output from the console, which printed the
AOP
Advice logger statement after and before the method calls.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
17:12:26.644+0530 INFO Starting LoggingAopSpringBootTest (started in D:\SpringBoot-AOP-Before-After-Example)
17:12:26.645+0530 INFO No active profile set, falling back to default profiles: default
17:12:28.458+0530 INFO Initializing ExecutorService 'applicationTaskExecutor'
17:12:28.825+0530 INFO Started LoggingAopSpringBootTest in 2.774 seconds (JVM running for 3.952)
17:12:29.261+0530 INFO ======TECHGEEKNEXT - Spring Boot AOP Before Advice Example
17:12:29.263+0530 INFO =====Started with method getEmployeeById
17:12:30.195+0530 INFO =====TECHGEEKNEXT - Spring Boot AOP After Advice Example
17:12:30.196+0530 INFO ======Completed execution of method getEmployeeById
17:12:30.227+0530 INFO Shutting down ExecutorService 'applicationTaskExecutor'
Download Source Code
The full source code for this article can be found on below.Download it here - Spring Boot + AOP + Before After Advice Example