How to Create Custom Spring Boot Annotations for Automatic Error Logging
Learn how to simplify repetitive error-handling code in Spring Boot by creating a custom @ErrorHandler annotation that leverages Spring AOP to automatically log exceptions, with step-by-step instructions, required dependencies, annotation definition, aspect implementation, and usage examples.
Have you ever been stuck writing the same code repeatedly and wished there was a way to simplify the process? If you use Spring Boot, you know annotations can make code concise, but built-in annotations may not cover every need.
Imagine a scenario where every method that needs to record an error must contain identical logging code. By creating a custom annotation you can encapsulate this repetitive logic, keep the codebase clean, and ensure consistent error handling across the application.
Step 1: Add Spring AOP Dependency
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>6.1.12</version>
</dependency>Step 2: Create Custom Annotation
Define a custom annotation to mark methods that require automatic error handling.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ErrorHandler {
}The @Retention(RUNTIME) makes the annotation available at runtime, while @Target(ElementType.METHOD) restricts its use to methods.
Define the Aspect
@Aspect
@Component
public class ErrorHandlerAspect {
private final ErrorLogRepository errorLogRepository;
public ErrorHandlerAspect(ErrorLogRepository errorLogRepository) {
this.errorLogRepository = errorLogRepository;
}
@Pointcut("@annotation(com.example.annotations.ErrorHandler)")
public void handleException() {}
@AfterThrowing(pointcut = "handleException()", throwing = "ex")
public void afterThrowing(Exception ex) {
System.out.println("Exception occurred: " + ex.getMessage());
ErrorLog errorLog = new ErrorLog();
errorLog.setErrorLogId(UUID.randomUUID().getMostSignificantBits() & Long.MAX_VALUE);
errorLog.setExceptionMessage(ex.getMessage());
errorLog.setExceptionStackTrace(getStackTraceAsString(ex));
errorLogRepository.save(errorLog);
}
private String getStackTraceAsString(Exception ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
return sw.toString();
}
}@Aspect marks the class as an aspect, enabling it to contain advice.
@Pointcut defines a pointcut named handleException that matches any method annotated with @ErrorHandler.
@AfterThrowing runs after a matched method throws an exception, receiving the exception object as ex.
The afterThrowing method logs the exception message, creates an ErrorLog entity with a unique ID and stack trace, and saves it via errorLogRepository. getStackTraceAsString converts the exception stack trace to a string for persistence.
Step 3: Use the Custom Annotation
@ErrorHandler
public void testExceptionLogging() {
// simulate an exception
if (true) {
throw new RuntimeException("Exception occurred");
}
}When this method is invoked, the runtime exception triggers the @AfterThrowing advice, which prints the message and records the error in the database.
Conclusion Custom annotations like @ErrorHandler in Spring Boot provide a powerful mechanism to automate repetitive tasks such as error logging. By leveraging Spring AOP, you can centralize error‑handling logic, keep your business code clean, and maintain a consistent logging strategy across the entire application.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
