How to Build a Custom Spring Boot Starter that Logs Method Execution Time
Learn how to create a custom Spring Boot starter named aspectlog-spring-boot-starter that automatically logs method execution times using AOP, covering project setup, Maven configuration, conditional loading, annotation definition, auto‑configuration class, META‑INF registration, and packaging for reuse in other projects.
Introduction
If you use Spring Boot, you will inevitably work with various spring-boot-starter modules. Creating a simple starter that logs method execution time only requires four steps.
Step 1 – Create a Maven Project
Starter projects follow a naming convention: spring-boot-starter-XX for official starters and XX-spring-boot-starter for third‑party extensions. Our starter will be named aspectlog-spring-boot-starter.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>aspectlog-spring-boot-starter</artifactId>
<version>1.0.2</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.15.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>The spring-boot-configuration-processor dependency lets Spring collect auto‑configuration conditions into META-INF/spring-autoconfigure-metadata.properties, improving startup time.
Step 2 – Write Auto‑Configuration Logic
2.1 Define the @AspectLog Annotation
package com.shanyuan.autoconfiguration.aspectlog;
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 AspectLog {
}2.2 Define Configuration Properties
package com.shanyuan.autoconfiguration.aspectlog;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties("aspectLog")
public class AspectLogProperties {
private boolean enable;
public boolean isEnable() { return enable; }
public void setEnable(boolean enable) { this.enable = enable; }
}2.3 Define the Auto‑Configuration Class
package com.shanyuan.autoconfiguration.aspectlog;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.core.PriorityOrdered;
@Aspect
@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
@Configuration
@ConditionalOnProperty(prefix = "aspectLog", name = "enable", havingValue = "true", matchIfMissing = true)
public class AspectLogAutoConfiguration implements PriorityOrdered {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Around("@annotation(com.shanyuan.autoconfiguration.aspectlog.AspectLog)")
public Object isOpen(ProceedingJoinPoint thisJoinPoint) throws Throwable {
String taskName = thisJoinPoint.getSignature().toString()
.substring(thisJoinPoint.getSignature().toString().indexOf(" "),
thisJoinPoint.getSignature().toString().indexOf("("))
.trim();
long time = System.currentTimeMillis();
Object result = thisJoinPoint.proceed();
logger.info("method:{} run :{} ms", taskName, (System.currentTimeMillis() - time));
return result;
}
@Override
public int getOrder() {
// Ensure transaction and other aspects run first
return Integer.MAX_VALUE;
}
}The @ConditionalOnProperty ensures the configuration is activated only when aspectLog.enable=true (or the property is missing, defaulting to true).
Step 3 – Register in META‑INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.shanyuan.autoconfiguration.aspectlog.AspectLogAutoConfigurationThis file tells Spring Boot to load the auto‑configuration class automatically.
Step 4 – Package and Test
After building the project with mvn install, include the generated JAR as a dependency in other Spring Boot applications. The starter will log execution time for any method annotated with @AspectLog when the property is enabled.
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.
