Build Your Own Spring Boot Starter: A Step‑by‑Step Guide
This tutorial walks you through creating a custom Spring Boot starter, covering project structure, naming conventions, auto‑configuration module, property management, Maven setup, sample usage, and best practices, enabling you to package reusable cross‑cutting functionality for any Spring application.
Introduction
When building a Spring application we often want to reuse cross‑cutting concerns instead of implementing them from scratch each time. Spring Boot provides the concept of a starter to package such functionality.
Cross‑cutting concern: behavior that spans multiple modules (e.g., an SDK).
Custom Starter
Before diving into implementation we look at the overall structure of a starter, which consists of two parts:
Auto‑Configure Module
Starter Module
Auto‑Configure Module
The auto‑configure module is a Maven/Gradle module that contains configuration classes. It can automatically contribute beans to the application context and provide access to external libraries.
⚠️ Spring’s reference guide recommends separating auto‑configuration into its own module, but for a private starter you may combine them.
Starter Module
A starter module is a Maven/Gradle module whose sole purpose is to bring in all dependencies required to “start” a feature. It usually depends on one or more auto‑configure modules.
Naming
Official starters are prefixed with spring-boot-starter- (e.g., spring-boot-starter-web). For a custom starter named acme you would use acme-spring-boot-starter and acme-spring-boot-autoconfigure. Avoid using Spring Boot’s reserved property namespaces such as server, management, or spring.
Parent Module Creation
Create a parent Maven module to manage dependency versions. Example directory layout:
.
├── pom.xml
├── rgyb-spring-boot-autoconfigure
├── rgyb-spring-boot-sample
└── rgyb-spring-boot-starterIn the parent pom.xml add a <dependencyManagement> section:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- add other global dependencies here -->
</dependencies>
</dependencyManagement>Auto‑Configure Module Construction
Create a configuration class, e.g. GreetingAutoConfiguration:
@Configuration
public class GreetingAutoConfiguration {
@Bean
public GreetingService greetingService(GreetingProperties greetingProperties) {
return new GreetingService(greetingProperties.getMembers());
}
}Define the service bean:
@AllArgsConstructor
public class GreetingService {
private List<String> members = new ArrayList<>();
public void sayHello() {
members.forEach(s -> System.out.println("hello " + s));
}
}Add META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=top.dayarch.autoconfigure.GreetingAutoConfigurationOptionally add conditional annotations to control activation:
@Configuration
@ConditionalOnProperty(value = "rgyb.greeting.enable", havingValue = "true")
@ConditionalOnClass(DummyEmail.class)
public class GreetingAutoConfiguration { ... }Configuration Properties Management
Bind properties with a @ConfigurationProperties class:
@Data
@ConfigurationProperties(prefix = "rgyb.greeting")
public class GreetingProperties {
/** enable flag */
private boolean enable = false;
/** list of members */
private List<String> members = new ArrayList<>();
}Add spring-boot-configuration-processor as an optional dependency so that IDEs generate spring-configuration-metadata.json for better completion.
Adding spring-boot-autoconfigure-processor generates spring-autoconfigure-metadata.properties, which speeds up startup by allowing Spring to filter configurations without loading classes.
Starter Module Construction
The starter module simply depends on the auto‑configure module. Its pom.xml includes the auto‑configure artifact and any other required dependencies:
<dependencies>
<dependency>
<groupId>top.dayarch.learnings</groupId>
<artifactId>rgyb-spring-boot-autoconfigure</artifactId>
<version>1.0.0.RELEASE</version>
</dependency>
<!-- add other necessary dependencies -->
</dependencies>Optionally add META-INF/spring.providers to list provided modules:
providers: rgyb-spring-boot-autoconfigureCreate Sample Module
Initialize a Spring Boot project with Spring Initializr, add the custom starter as a dependency, and configure application.yml:
rgyb:
greeting:
enable: true
members:
- 李雷
- 韩梅梅Write a test class that autowires GreetingService and calls sayHello():
@Autowired(required = false)
private GreetingService greetingService;
@Test
public void testGreeting() {
greetingService.sayHello();
}Running the test prints:
hello 李雷
hello 韩梅梅Conclusion
The tutorial walks through the complete lifecycle of a Spring Boot starter: project layout, naming conventions, auto‑configuration, property handling, packaging, and usage in a sample application.
Knowledge Points
Dependency optional
Auto‑configure dependencies are marked optional=true to avoid unwanted transitive dependencies.
spring.factories
Spring Boot loads this file via SpringFactoriesLoader to discover auto‑configuration classes.
Practical Example
Refer to mybatis-spring-boot-starter for a real‑world non‑official starter.
Soul‑Searching Questions
Why are @ConditionalOnProperty entries not written into spring-autoconfigure-metadata.properties?
How to set up a private Maven repository for publishing your starter?
Is your light still on?
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.
