Implementing Custom Starters
1. Understanding Spring Boot Starter Structure
Two-Module Layout
my-feature-spring-boot-autoconfigure ← @AutoConfiguration + @ConfigurationProperties
my-feature-spring-boot-starter ← empty pom; pulls autoconfigure + transitive deps
2. Creating Starter Module (spring-boot-starter-*)
| Naming Convention |
Rule |
| Official |
spring-boot-starter-X (reserved) |
| Third-party |
X-spring-boot-starter |
3. Creating Auto-Configuration Classes (@AutoConfiguration)
Example: Auto-configuration class
@AutoConfiguration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean @ConditionalOnMissingBean
MyService myService(MyProperties props) {
return new MyService(props.getEndpoint(), props.getApiKey());
}
}
4. Using @ConditionalOnClass for Auto-Configuration
| Condition |
Triggers When |
@ConditionalOnClass |
Class on classpath |
@ConditionalOnMissingClass |
Class absent |
@ConditionalOnBean |
Bean exists |
@ConditionalOnMissingBean |
No such bean defined |
@ConditionalOnProperty |
Property matches |
@ConditionalOnWebApplication |
Servlet/Reactive web app |
5. Creating Configuration Properties (@ConfigurationProperties)
Example: Configuration properties as record
@ConfigurationProperties("myfeature")
public record MyProperties(String endpoint, String apiKey, Duration timeout) {}
6. Registering Auto-Configuration (spring.factories, AutoConfiguration.imports)
Example: Register auto-configuration via imports file
# src/main/resources/META-INF/spring/
# org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.myfeature.MyAutoConfiguration
Note: spring.factories for autoconfig is deprecated since Boot 2.7
— use AutoConfiguration.imports.
7. Implementing Fail-Fast Configuration Validation
Example: Validated configuration properties for starter
@ConfigurationProperties("myfeature")
@Validated
public record MyProperties(
@NotBlank String endpoint,
@NotBlank String apiKey,
@DurationMin(seconds = 1) Duration timeout) {}
8. Creating Starter Documentation
| Artifact |
Purpose |
| README.md |
Quick start, properties |
spring-configuration-metadata.json |
IDE autocomplete |
additional-spring-configuration-metadata.json |
Manual hints/descriptions |
9. Publishing Custom Starters
| Target |
How |
| Maven Central |
Sonatype OSSRH + GPG sign |
| GitHub Packages |
github server in settings.xml |
| Internal Nexus/Artifactory |
Distribution-management section |
10. Testing Custom Starters
Example: Test auto-configuration with context runner
class MyAutoConfigurationTests {
private final ApplicationContextRunner runner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(MyAutoConfiguration.class));
@Test void registersBeanWhenPropertiesSet() {
runner.withPropertyValues("myfeature.endpoint=http://x", "myfeature.api-key=k")
.run(ctx -> assertThat(ctx).hasSingleBean(MyService.class));
}
@Test void backsOffIfUserDefinedBean() {
runner.withUserConfiguration(UserConfig.class)
.run(ctx -> assertThat(ctx.getBean(MyService.class)).isInstanceOf(MyServiceStub.class));
}
}