Building Custom Starters in Spring Boot 3

Spring Boot is known for its opinionated auto-configuration and rapid setup capabilities. One of the hidden gems of its ecosystem is custom starters β€” reusable libraries that help you abstract configuration, dependencies, and auto-configuration logic into standalone modules. In this tutorial, we will walk through building custom starters in Spring Boot 3.

Whether you’re building internal tooling or want to reuse boilerplate code across projects, custom starters in Spring Boot 3 are the key to modular, scalable Java development.

Building Custom Starters in Spring Boot 3

🎯 What is a Spring Boot Starter?

A starter is simply a Maven/Gradle dependency that:

  • Includes transitive dependencies.
  • Optionally provides auto-configuration logic.
  • May expose Spring components like services or configurations.

Spring Boot itself offers many starters like:

  • spring-boot-starter-web
  • spring-boot-starter-data-jpa
  • spring-boot-starter-security

Let’s build our own!

πŸ›  Project Structure

We will create:

  • A custom starter module (e.g., kscodes-greeting-starter)
  • A demo application that uses it

spring-boot-custom-starter/
β”œβ”€β”€ kscodes-greeting-starter/
β”‚   └── src/main/java/com/kscodes/springboot/greeting/
β”œβ”€β”€ greeting-app/
β”‚   └── src/main/java/com/kscodes/springboot/demo/

πŸ“¦ Step 1: Create the Custom Starter Module

πŸ”Ή pom.xml for kscodes-greeting-starter




    com.kscodes.springboot
    kscodes-greeting-starter
    1.0.0
    jar

    
        
            org.springframework.boot
            spring-boot-autoconfigure
        
    


✨ Step 2: Create the Configuration Properties Class


package com.kscodes.springboot.greeting;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "kscodes.greeting")
public class GreetingProperties {
    private String message = "Hello from custom starter!";

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

🧠 Step 3: Create the AutoConfiguration Class


package com.kscodes.springboot.greeting;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

@Configuration
@EnableConfigurationProperties(GreetingProperties.class)
@ConditionalOnProperty(prefix = "kscodes.greeting", name = "enabled", havingValue = "true", matchIfMissing = true)
public class GreetingAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public GreetingService greetingService(GreetingProperties properties) {
        return new GreetingService(properties.getMessage());
    }
}

🧾 Step 4: Create the Service Class


package com.kscodes.springboot.greeting;

public class GreetingService {
    private final String message;

    public GreetingService(String message) {
        this.message = message;
    }

    public String greet(String name) {
        return message + " " + name + "!";
    }
}

πŸ“˜ Step 5: Register the Auto-Configuration File

In src/main/resources/META-INF/spring.factories:


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.kscodes.springboot.greeting.GreetingAutoConfiguration

πŸ§ͺ Step 6: Create a Demo App to Use the Starter

πŸ”Ή Add Dependency in greeting-app/pom.xml



    com.kscodes.springboot
    kscodes-greeting-starter
    1.0.0



πŸ”§ Step 7: Use in the Application


package com.kscodes.springboot.demo;

import com.kscodes.springboot.greeting.GreetingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GreetingApp implements CommandLineRunner {

    @Autowired
    private GreetingService greetingService;

    public static void main(String[] args) {
        SpringApplication.run(GreetingApp.class, args);
    }

    @Override
    public void run(String... args) {
        System.out.println(greetingService.greet("Ketan"));
    }
}

βš™οΈ Optional: Customize the Message via application.properties


kscodes.greeting.message=Namaste from KSCodes Starter
kscodes.greeting.enabled=true

πŸ’‘ Advantages of Using Custom Starters in Spring Boot 3

  • Promote code reuse and standardization
  • Reduce repetitive configurations
  • Ideal for internal enterprise platforms and shared teams
  • Perfect for open-source starter kits

You can abstract anything from logging, monitoring, metrics, service discovery clients, internal SDKs, etc.

🧹 Tips & Best Practices

  1. Name your starter clearly: *-starter
  2. Provide sane defaults using @ConfigurationProperties
  3. Use @ConditionalOn* annotations for flexibility
  4. Register your spring.factories or spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports in Spring Boot 3.1+

πŸ”š Conclusion

Creating custom starters in Spring Boot 3 is an elegant way to modularize your configurations and reuse business logic. Whether you’re streamlining internal SDKs or building reusable Spring components, custom starters reduce boilerplate and enhance consistency across teams.

With this guide, you can now start building custom starters in Spring Boot 3 for your own needs or for the developer community.

βœ… Summary

  • βœ… Use spring-boot-autoconfigure
  • βœ… Create @ConfigurationProperties and @Configuration with conditional beans
  • βœ… Register your config in spring.factories
  • βœ… Use it like any other Spring Boot starter