Creating a Custom Starter

Why Build a Starter

Large companies have many Spring Boot services that need the same setup: audit logging, a standard error format, a company HTTP client. A custom starter packages that setup so each service just adds one dependency.

shopease-audit-spring-boot-starter (jar)
 ├── AuditProperties          @ConfigurationProperties("shopease.audit")
 ├── AuditLogger              the actual feature
 ├── AuditAutoConfiguration   @AutoConfiguration + @Conditional...
 └── META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

The Auto-Configuration Class

@ConfigurationProperties(prefix = "shopease.audit")
public record AuditProperties(boolean enabled, String serviceName) {
    public AuditProperties {
        if (serviceName == null) serviceName = "unknown-service";
    }
}

public class AuditLogger {
    private final String service;
    public AuditLogger(String service) { this.service = service; }
    public void log(String user, String action) {
        System.out.printf("[AUDIT] service=%s user=%s action=%s%n", service, user, action);
    }
}

@AutoConfiguration
@EnableConfigurationProperties(AuditProperties.class)
@ConditionalOnProperty(name = "shopease.audit.enabled", havingValue = "true", matchIfMissing = true)
public class AuditAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    AuditLogger auditLogger(AuditProperties props) {
        return new AuditLogger(props.serviceName());
    }
}

Example

Register it (one fully qualified class name per line):

src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.shopease.audit.AuditAutoConfiguration

Using the Starter

<dependency>
    <groupId>com.shopease</groupId>
    <artifactId>shopease-audit-spring-boot-starter</artifactId>
    <version>1.0.0</version>
</dependency>

Example

application.yml

shopease:
  audit:
    service-name: order-service
@Service
@RequiredArgsConstructor
public class OrderService {
    private final AuditLogger audit;     // injected, no @Bean needed in this service

    public void cancel(Long orderId, String user) {
        audit.log(user, "CANCEL_ORDER " + orderId);
    }
}

Tip: Naming rule: official starters are spring-boot-starter-x; your own should be x-spring-boot-starter.