Mastering Custom Spring Boot Starters: Version Differences & Real‑World AOP Example
This article explains what custom Spring Boot starters are, why they are useful, outlines the annotation and configuration file changes across Spring Boot 2.6, 2.7 and 3.x, and provides a complete AOP‑based starter implementation with code samples.
1. Introduction
Custom starters are a Spring Boot extension mechanism that lets developers package related dependencies, configuration, and auto‑configuration classes into a reusable module. By adding the starter as a Maven or Gradle dependency, Spring Boot automatically scans and loads its configuration, providing one‑stop service for the required technologies.
Why create a custom starter? It enables reuse of common modules (e.g., security, logging, validation) across projects, simplifies dependency management, reduces configuration errors, and improves maintainability.
2. Differences Between Spring Boot Versions
2.1 Annotation changes
Before 2.7, auto‑configuration classes are marked with @Configuration . Starting with 2.7, the new @AutoConfiguration meta‑annotation is used, which itself is annotated with @Configuration to keep the class a standard configuration class.
<code>@Configuration(proxyBeanMethods = false)
@AutoConfigureBefore
@AutoConfigureAfter
public @interface AutoConfiguration {
@AliasFor(annotation = Configuration.class)
String value() default "";
@AliasFor(annotation = AutoConfigureBefore.class, attribute = "value")
Class<?>[] before() default {};
@AliasFor(annotation = AutoConfigureBefore.class, attribute = "name")
String[] beforeName() default {};
@AliasFor(annotation = AutoConfigureAfter.class, attribute = "value")
Class<?>[] after() default {};
@AliasFor(annotation = AutoConfigureAfter.class, attribute = "name")
String[] afterName() default {};
}</code>2.2 Configuration file locations
Before 2.7, Spring Boot looks for META-INF/spring.factories where EnableAutoConfiguration keys list the configuration classes.
<code>org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.pack.aop.autoconfigure.PackAspectAutoConfiguration,\
xxx,\
yyy,\
zzz</code>From 2.7 onward, the file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports is used, listing one class per line.
<code>com.pack.aop.autoconfigure.PackAspectAutoConfiguration
xxx
yyy
zzz</code>In Spring Boot 3.x only the AutoConfiguration.imports file is consulted.
2.3 Controlling auto‑configuration order
Pre‑2.7 you use @AutoConfigureBefore or @AutoConfigureAfter on a @Configuration class.
<code>@Configuration
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
public class PackAspectAutoConfiguration {}
</code>From 2.7 you can set the order directly on @AutoConfiguration via its before and after attributes.
<code>@AutoConfiguration(before = {DataSourceAutoConfiguration.class})
public class PackAspectAutoConfiguration {}
</code>3. Practical Example – AOP Timing Starter
The example demonstrates a starter that records method execution time using Spring AOP.
3.1 Define the aspect
<code>@Aspect
public class TimeAspect {
@Pointcut("@annotation(time)")
private void time(RecordTime time) {}
@Around("time(time)")
public Object record(ProceedingJoinPoint pjp, RecordTime time) throws Throwable {
StopWatch clock = new StopWatch(getClass().getSimpleName());
Object ret = null;
try {
Signature signature = pjp.getSignature();
clock.start(signature.getDeclaringType().getName() + "#" + signature.getName());
ret = pjp.proceed();
return ret;
} finally {
clock.stop();
System.out.printf("Execution time: %s%n", clock.prettyPrint());
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RecordTime {
String value() default "";
}
</code>3.2 Auto‑configuration class
<code>@AutoConfiguration
@ConditionalOnProperty(prefix = "pack.aop", name = "enabled", matchIfMissing = false)
public class RecordTimeAutoConfiguration {
@Bean
TimeAspect timeAspect() {
return new TimeAspect();
}
}
</code>3.3 Register the starter
Create the file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports with the following line:
<code>com.component.aop.time.RecordTimeAutoConfiguration</code>After packaging the starter, add it as a dependency and annotate any method you want to monitor with @RecordTime . The aspect will log the execution duration.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
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.