Creating a Custom Spring Boot Auto‑Configuration and Starter
This article demonstrates how to build a custom Spring Boot auto‑configuration and starter, including a conditional annotation, a WriterTemplate utility that writes to a database or file, Maven setup, property binding, and a usage example that shows the bean being auto‑configured and invoked.
Spring Boot provides automatic configuration for third‑party libraries, and this article shows how to create a custom auto‑configuration and starter named funny‑spring‑boot‑starter .
First, a custom conditional annotation @ConditionalCustom is defined, backed by a MyCondition class that checks the presence of configuration properties.
package com.example._003configtest.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Map;
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Map
attrs = metadata.getAnnotationAttributes(ConditionalCustom.class.getName());
String[] vals = (String[]) attrs.get("value");
Environment env = context.getEnvironment();
for (String v : vals) {
if (env.getProperty(v) == null) {
return false;
}
}
return true;
}
}The annotation itself is simple:
package com.example._003configtest.annotation;
import com.example._003configtest.condition.MyCondition;
import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(MyCondition.class)
public @interface ConditionalCustom {
String[] value() default {};
}A utility class WriterTemplate writes messages either to a database table funny_message (creating it if missing) or to a file, depending on whether a DataSource is supplied.
The starter’s pom.xml declares a dependency on the core funny library and on spring-boot-starter . The auto‑configuration class FunnyAutoConfiguration is annotated with @Configuration, @ConditionalOnClass(WriterTemplate.class), @EnableConfigurationProperties(FunnyProperties.class) and @AutoConfigureAfter(DataSourceAutoConfiguration.class). It defines two @Bean methods: one that creates a WriterTemplate from a DataSource (high priority) and another that creates it from a file path and charset (lower priority).
package com.example.funnyspringbootstarter.autoconfig;
import io.WriterTemplate;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.*;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.sql.SQLException;
@Configuration
@ConditionalOnClass(WriterTemplate.class)
@EnableConfigurationProperties(FunnyProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class FunnyAutoConfiguration {
private final FunnyProperties properties;
public FunnyAutoConfiguration(FunnyProperties properties) {
this.properties = properties;
}
@Bean(destroyMethod = "close")
@ConditionalOnSingleCandidate(DataSource.class)
@ConditionalOnMissingBean
@AutoConfigureOrder(99)
public WriterTemplate writerTemplate(DataSource dataSource) throws SQLException {
return new WriterTemplate(dataSource);
}
@Bean(destroyMethod = "close")
@ConditionalOnMissingBean
@AutoConfigureOrder(199)
public WriterTemplate writerTemplate2() throws FileNotFoundException {
File f = new File(this.properties.getDest());
Charset charset = Charset.forName(this.properties.getCharset());
return new WriterTemplate(f, charset);
}
}The accompanying FunnyProperties class binds the org.test.* properties (dest and charset) from application.properties .
Finally, the starter is registered in META-INF/spring.factories , and a sample application demonstrates retrieving the WriterTemplate bean and calling write() , which writes either to the configured file or to the funny_message table depending on the presence of a datasource.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.