Core starter providing fundamental building blocks for Spring Boot applications with auto-configuration support, logging, and YAML parsing
—
Type-safe configuration property binding system with validation support, enabling external configuration management for Spring Boot applications.
Bind external configuration properties to Java objects with type safety and validation.
/**
* Annotation for externalized configuration. Add this to a class definition or a
* @Bean method in a @Configuration class if you want to bind and validate some
* external Properties (e.g. from a .properties file)
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface ConfigurationProperties {
/**
* The name prefix of the properties that are valid to bind to this object
* @return the name prefix of the properties to bind
*/
String value() default "";
/**
* The name prefix of the properties that are valid to bind to this object
* @return the name prefix of the properties to bind
*/
String prefix() default "";
/**
* Flag to indicate that when binding to this object invalid fields should be ignored
* @return whether to ignore invalid fields
*/
boolean ignoreInvalidFields() default false;
/**
* Flag to indicate that when binding to this object unknown fields should be ignored
* @return whether to ignore unknown fields
*/
boolean ignoreUnknownFields() default true;
}
/**
* Enable support for ConfigurationProperties annotated classes
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface EnableConfigurationProperties {
/**
* The configuration properties classes to register
* @return the classes to register
*/
Class<?>[] value() default {};
}
/**
* Scan for configuration properties classes in the specified packages
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface ConfigurationPropertiesScan {
/**
* Alias for basePackages()
* @return the base packages
*/
String[] value() default {};
/**
* Base packages to scan for configuration properties classes
* @return the base packages
*/
String[] basePackages() default {};
/**
* Type-safe alternative to basePackages() for specifying packages to scan
* @return the base package classes
*/
Class<?>[] basePackageClasses() default {};
}Usage Examples:
// Basic configuration properties class
@ConfigurationProperties(prefix = "app.database")
public class DatabaseProperties {
private String url;
private String username;
private String password;
private int maxConnections = 10;
// Getters and setters
public String getUrl() { return url; }
public void setUrl(String url) { this.url = url; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public int getMaxConnections() { return maxConnections; }
public void setMaxConnections(int maxConnections) { this.maxConnections = maxConnections; }
}
// Enable configuration properties in main class
@SpringBootApplication
@EnableConfigurationProperties(DatabaseProperties.class)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// Use configuration properties in a service
@Service
public class DatabaseService {
private final DatabaseProperties databaseProperties;
public DatabaseService(DatabaseProperties databaseProperties) {
this.databaseProperties = databaseProperties;
}
public void connect() {
System.out.println("Connecting to: " + databaseProperties.getUrl());
}
}Control how properties are bound to Java objects.
/**
* Annotation that can be used to indicate that configuration properties should
* be bound using constructor arguments rather than by calling setters
*/
@Target({ElementType.CONSTRUCTOR, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface ConstructorBinding {
}
/**
* Annotation that can be used to specify a default value when binding configuration properties
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@interface DefaultValue {
/**
* The default value to use if no property is found
* @return the default value
*/
String[] value() default {};
}
/**
* Annotation that can be used to indicate that a field in a ConfigurationProperties
* object should be treated as if it were a nested type
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface NestedConfigurationProperty {
}
/**
* Annotation that can be used to indicate that a ConfigurationProperties field is deprecated
*/
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface DeprecatedConfigurationProperty {
/**
* The reason for the deprecation
* @return the deprecation reason
*/
String reason() default "";
/**
* The replacement property that should be used instead
* @return the replacement property
*/
String replacement() default "";
}Usage Examples:
// Constructor binding example
@ConfigurationProperties(prefix = "app.server")
@ConstructorBinding
public class ServerProperties {
private final String host;
private final int port;
private final boolean ssl;
public ServerProperties(
@DefaultValue("localhost") String host,
@DefaultValue("8080") int port,
@DefaultValue("false") boolean ssl) {
this.host = host;
this.port = port;
this.ssl = ssl;
}
public String getHost() { return host; }
public int getPort() { return port; }
public boolean isSsl() { return ssl; }
}
// Nested configuration properties example
@ConfigurationProperties(prefix = "app")
public class ApplicationProperties {
@NestedConfigurationProperty
private final DatabaseConfig database = new DatabaseConfig();
@NestedConfigurationProperty
private final SecurityConfig security = new SecurityConfig();
public DatabaseConfig getDatabase() { return database; }
public SecurityConfig getSecurity() { return security; }
public static class DatabaseConfig {
private String url;
private String username;
// getters and setters
}
public static class SecurityConfig {
private boolean enabled = true;
// getters and setters
}
}
// Deprecated property example
@ConfigurationProperties(prefix = "app.legacy")
public class LegacyProperties {
@DeprecatedConfigurationProperty(
reason = "Use 'app.new.timeout' instead",
replacement = "app.new.timeout"
)
private Duration oldTimeout;
// getters and setters
}Utilities for mapping and validating configuration properties.
/**
* Utility that can be used to map values from a supplied source to a destination
*/
public final class PropertyMapper {
/**
* Return a new PropertyMapper instance
* @return a new property mapper
*/
public static PropertyMapper get();
/**
* Return a new Source from the specified value supplier that can be used to
* perform the mapping
* @param value the value supplier
* @return a property source
*/
public <T> Source<T> from(T value);
/**
* Return a new Source from the specified value supplier that can be used to
* perform the mapping
* @param supplier the value supplier
* @return a property source
*/
public <T> Source<T> from(Supplier<T> supplier);
/**
* Return a new PropertyMapper that won't map null values
* @return a property mapper that ignores null values
*/
public PropertyMapper alwaysApplyingWhenNonNull();
/**
* A source that is in the process of being mapped
*/
public final class Source<T> {
/**
* Return an adapted version of the source with the specified type
* @param adapter the adapter to use
* @return a new adapted source
*/
public <R> Source<R> as(Function<T, R> adapter);
/**
* Return a filtered version of the source that won't map non-null values or values that don't match the specified predicate
* @param predicate the predicate to use to test the value
* @return a new filtered source
*/
public Source<T> when(Predicate<T> predicate);
/**
* Return a filtered version of the source that will only map values that are not equal to the specified value
* @param value the value to check
* @return a new filtered source
*/
public Source<T> whenNot(T value);
/**
* Complete the mapping by passing the current value to the specified consumer
* @param consumer the consumer that should accept the value
*/
public void to(Consumer<T> consumer);
/**
* Complete the mapping for any non-null value by passing it to the specified consumer
* @param consumer the consumer that should accept the value
*/
public void toCall(Runnable consumer);
}
}Usage Examples:
// Property mapping example
@ConfigurationProperties(prefix = "app.server")
public class ServerProperties {
private String host;
private int port;
private Duration timeout;
// Constructor using PropertyMapper
public void configureServer(ServerConfigurer configurer) {
PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();
map.from(this::getHost).to(configurer::setHost);
map.from(this::getPort).to(configurer::setPort);
map.from(this::getTimeout).as(Duration::toMillis).to(configurer::setTimeoutMillis);
}
// getters and setters
}
// Advanced property mapping with conditions
public void configureTomcat(TomcatServletWebServerFactory factory) {
PropertyMapper propertyMapper = PropertyMapper.get();
propertyMapper.from(properties::getMaxThreads)
.when(maxThreads -> maxThreads > 0)
.to(factory::setMaxThreads);
propertyMapper.from(properties::getMinSpareThreads)
.whenNot(0)
.to(factory::setMinSpareThreads);
propertyMapper.from(properties::getConnectionTimeout)
.as(Duration::toMillis)
.as(Math::toIntExact)
.to(factory::setConnectionTimeout);
}Support for generating and processing configuration metadata.
/**
* Annotation that marks a field or method as being related to configuration metadata
*/
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface ConfigurationMetadata {
/**
* A description of the configuration item
* @return the description
*/
String description() default "";
/**
* The default value of the configuration item
* @return the default value
*/
String defaultValue() default "";
/**
* Whether the configuration item is deprecated
* @return true if deprecated
*/
boolean deprecated() default false;
}Integration with Bean Validation (JSR-303) for configuration properties validation.
/**
* Configuration properties can be validated using standard Bean Validation annotations
* when javax.validation is on the classpath
*/
// Example validated configuration properties class
@ConfigurationProperties(prefix = "app.mail")
@Validated
public class MailProperties {
@NotBlank
private String host;
@Range(min = 1, max = 65535)
private int port = 587;
@Email
private String username;
@Valid
@NestedConfigurationProperty
private final Smtp smtp = new Smtp();
public static class Smtp {
@NotNull
private Duration timeout = Duration.ofSeconds(30);
@Min(1)
@Max(10)
private int retries = 3;
// getters and setters
}
// getters and setters
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter