Spring Boot + AOP + Logging Example (2024)
In this tutorial, we'll see how to use AspectJ (aop advice) to measure method execution time as a logging mechanism in Spring Boot applications 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-Logging-Example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringBoot-AOP-Logging-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. It logs the overall method
execution time in
the log file and records the method start and end times.
package com.techgeeknext.aop;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Aspect
@Component
public class LoggingAspectExample {
private static final Logger LOGGER = LogManager.getLogger(LoggingAspectExample.class);
@Around("execution(* com.techgeeknext..*(..)))")
public Object logMethodExecutionTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) proceedingJoinPoint.getSignature();
final StopWatch stopWatch = new StopWatch();
//calculate method execution time
stopWatch.start();
Object result = proceedingJoinPoint.proceed();
stopWatch.stop();
//Log method execution time
LOGGER.info("TECHGEEKNEXT - Spring Boot Logging AOP EXAMPLE - Execution time of "
+ methodSignature.getDeclaringType().getSimpleName() // Class Name
+ "." + methodSignature.getName() + " " // Method Name
+ ":: " + stopWatch.getTotalTimeMillis() + " ms");
return result;
}
}
We can also use aspectj @Before
and @After
annotation advice to call before and after method execution.
Refer Spring Boot + AOP + Before After Advice Example
We can also use aspectj @AfterThrowing
annotation advice for exception handling in the application.
Refer Spring Boot AOP Exception Handling
Employee Service to test Advice
We'll create simple service so that we can test our AOP logging 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 with method execution time.
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)
16:10:30.705+0530 INFO Starting LoggingAopSpringBootTest on LAPTOP-S6R44CQL with PID 29016 (started in D:\SpringBoot-AOP-Logging-Example)
16:10:30.706+0530 INFO No active profile set, falling back to default profiles: default
16:10:32.526+0530 INFO Initializing ExecutorService 'applicationTaskExecutor'
16:10:32.845+0530 INFO Started LoggingAopSpringBootTest in 2.681 seconds (JVM running for 3.823)
16:10:34.772+0530 INFO
TECHGEEKNEXT - Spring Boot Logging AOP EXAMPLE -
Execution time of EmployeeService.getEmployeeById :: 1523 ms
16:10:34.800+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 + Logging Example