or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdconfiguration.mdcontext.mdconversion.mdindex.mdjson.mdlogging.mdweb.md

configuration.mddocs/

0

# Configuration Management

1

2

Spring Boot's configuration management system provides type-safe property binding, validation, and flexible property source handling. It enables external configuration through properties files, environment variables, command-line arguments, and more.

3

4

## Capabilities

5

6

### Configuration Properties Annotations

7

8

Core annotations for binding external configuration to Java objects.

9

10

```java { .api }

11

/**

12

* Annotation for externalized configuration. Binds and validates external

13

* configuration (e.g. from properties files)

14

*/

15

@Target({ElementType.TYPE, ElementType.METHOD})

16

@Retention(RetentionPolicy.RUNTIME)

17

@Documented

18

public @interface ConfigurationProperties {

19

20

/**

21

* The name prefix of the properties that are valid to bind to this object.

22

* Synonym for prefix(). A valid prefix is defined by one or more valid

23

* {@code ConfigurationPropertyName} segments separated by "."

24

* @return the name prefix of the properties to bind

25

*/

26

@AliasFor("prefix")

27

String value() default "";

28

29

/**

30

* The name prefix of the properties that are valid to bind to this object.

31

* Synonym for value(). A valid prefix is defined by one or more valid

32

* {@code ConfigurationPropertyName} segments separated by "."

33

* @return the name prefix of the properties to bind

34

*/

35

@AliasFor("value")

36

String prefix() default "";

37

38

/**

39

* Flag to indicate that when binding to this object invalid fields should be ignored.

40

* Invalid means invalid according to the binder that is used, and usually this means

41

* fields of the wrong type (or that cannot be coerced into the correct type).

42

* @return the flag value (default false)

43

*/

44

boolean ignoreInvalidFields() default false;

45

46

/**

47

* Flag to indicate that when binding to this object fields with periods in their

48

* names should be ignored.

49

* @return the flag value (default true)

50

*/

51

boolean ignoreUnknownFields() default true;

52

}

53

54

/**

55

* Enable support for ConfigurationProperties annotated classes

56

*/

57

@Target(ElementType.TYPE)

58

@Retention(RetentionPolicy.RUNTIME)

59

@Documented

60

@Import(EnableConfigurationPropertiesRegistrar.class)

61

public @interface EnableConfigurationProperties {

62

63

/**

64

* The configuration properties classes to register

65

* @return the classes to register

66

*/

67

Class<?>[] value() default {};

68

}

69

70

/**

71

* Scan for ConfigurationProperties annotated classes

72

*/

73

@Target(ElementType.TYPE)

74

@Retention(RetentionPolicy.RUNTIME)

75

@Documented

76

@Import(ConfigurationPropertiesScanRegistrar.class)

77

public @interface ConfigurationPropertiesScan {

78

79

/**

80

* Alias for the basePackages() attribute. Allows for more concise annotation

81

* declarations e.g.: {@code @ConfigurationPropertiesScan("org.my.pkg")}

82

* instead of {@code @ConfigurationPropertiesScan(basePackages="org.my.pkg")}

83

* @return the base packages to scan

84

*/

85

@AliasFor("basePackages")

86

String[] value() default {};

87

88

/**

89

* Base packages to scan for annotated configuration properties classes

90

* @return the base packages to scan

91

*/

92

@AliasFor("value")

93

String[] basePackages() default {};

94

95

/**

96

* Type-safe alternative to basePackages() for specifying the packages to scan

97

* @return classes that are in the base packages

98

*/

99

Class<?>[] basePackageClasses() default {};

100

}

101

102

/**

103

* Indicates that a field in a ConfigurationProperties object should be treated as

104

* if it were a nested type

105

*/

106

@Target({ElementType.FIELD, ElementType.METHOD})

107

@Retention(RetentionPolicy.RUNTIME)

108

@Documented

109

public @interface NestedConfigurationProperty {

110

}

111

112

/**

113

* Indicates that a getter in a ConfigurationProperties object is deprecated

114

*/

115

@Target({ElementType.METHOD})

116

@Retention(RetentionPolicy.RUNTIME)

117

@Documented

118

public @interface DeprecatedConfigurationProperty {

119

120

/**

121

* The reason for the deprecation

122

* @return the reason for the deprecation

123

*/

124

String reason() default "";

125

126

/**

127

* The replacement property that should be used instead

128

* @return the replacement property

129

*/

130

String replacement() default "";

131

}

132

```

133

134

**Usage Examples:**

135

136

```java

137

// Basic configuration properties class

138

@ConfigurationProperties(prefix = "app")

139

@Component

140

public class AppProperties {

141

142

private String name = "My Application";

143

private Duration timeout = Duration.ofSeconds(30);

144

private final Security security = new Security();

145

146

// Getters and setters

147

public String getName() { return name; }

148

public void setName(String name) { this.name = name; }

149

150

public Duration getTimeout() { return timeout; }

151

public void setTimeout(Duration timeout) { this.timeout = timeout; }

152

153

@NestedConfigurationProperty

154

public Security getSecurity() { return security; }

155

156

public static class Security {

157

private String username;

158

private String password;

159

private List<String> roles = new ArrayList<>();

160

161

// Getters and setters

162

public String getUsername() { return username; }

163

public void setUsername(String username) { this.username = username; }

164

165

public String getPassword() { return password; }

166

public void setPassword(String password) { this.password = password; }

167

168

public List<String> getRoles() { return roles; }

169

public void setRoles(List<String> roles) { this.roles = roles; }

170

}

171

}

172

173

// Enable configuration properties

174

@Configuration

175

@EnableConfigurationProperties(AppProperties.class)

176

public class AppConfiguration {

177

178

@Autowired

179

private AppProperties properties;

180

181

@Bean

182

public MyService myService() {

183

return new MyService(properties.getName(), properties.getTimeout());

184

}

185

}

186

187

// Scan for configuration properties

188

@SpringBootApplication

189

@ConfigurationPropertiesScan("com.example.config")

190

public class Application {

191

public static void main(String[] args) {

192

SpringApplication.run(Application.class, args);

193

}

194

}

195

```

196

197

### Property Binding Core

198

199

Core classes for binding configuration properties with type safety and validation.

200

201

```java { .api }

202

/**

203

* A container object to bind from some ConfigurationPropertySources

204

*/

205

public class Binder {

206

207

/**

208

* Create a new Binder instance for the specified sources

209

* @param sources the configuration property sources

210

*/

211

public Binder(ConfigurationPropertySource... sources);

212

213

/**

214

* Create a new Binder instance for the specified sources

215

* @param sources the configuration property sources

216

* @param placeholdersResolver strategy to resolve any property placeholders

217

* @param conversionService the conversion service to convert bound properties

218

* @param propertyEditorInitializer used to configure property editors that can

219

* convert values

220

*/

221

public Binder(Iterable<ConfigurationPropertySource> sources,

222

PlaceholdersResolver placeholdersResolver,

223

ConversionService conversionService,

224

Consumer<PropertyEditorRegistry> propertyEditorInitializer);

225

226

/**

227

* Return a binder instance that is backed by the specified Environment and uses

228

* all qualifier and conversion rules found in the environment

229

* @param environment the environment (must not be null)

230

* @return a binder instance

231

*/

232

public static Binder get(Environment environment);

233

234

/**

235

* Bind the specified target Class using this binder's property sources

236

* @param name the configuration property name to bind

237

* @param target the target class

238

* @return the binding result (never null)

239

*/

240

public <T> BindResult<T> bind(String name, Class<T> target);

241

242

/**

243

* Bind the specified target Bindable using this binder's property sources

244

* @param name the configuration property name to bind

245

* @param target the target bindable

246

* @return the binding result (never null)

247

*/

248

public <T> BindResult<T> bind(String name, Bindable<T> target);

249

250

/**

251

* Bind the specified target Bindable using this binder's property sources

252

* @param name the configuration property name to bind

253

* @param target the target bindable

254

* @return the binding result (never null)

255

*/

256

public <T> BindResult<T> bind(ConfigurationPropertyName name, Bindable<T> target);

257

258

/**

259

* Bind the specified target Bindable using this binder's property sources or

260

* create a new instance using the type of the Bindable if the result of the

261

* binding is null

262

* @param name the configuration property name to bind

263

* @param target the target bindable

264

* @return the bound or created object (never null)

265

*/

266

public <T> T bindOrCreate(String name, Bindable<T> target);

267

}

268

269

/**

270

* A source of ConfigurationProperty objects

271

*/

272

public interface ConfigurationPropertySource {

273

274

/**

275

* Return a single ConfigurationProperty from the source or null if no

276

* property can be found

277

* @param name the name of the property (must not be null)

278

* @return the associated object or null

279

*/

280

ConfigurationProperty getConfigurationProperty(ConfigurationPropertyName name);

281

282

/**

283

* Return a variant of this source that supports name aliases

284

* @param aliases the name aliases

285

* @return a new source that supports name aliases

286

*/

287

default ConfigurationPropertySource withAliases(ConfigurationPropertyNameAliases aliases) {

288

return new AliasedConfigurationPropertySource(this, aliases);

289

}

290

}

291

292

/**

293

* A configuration property name

294

*/

295

public final class ConfigurationPropertyName implements Comparable<ConfigurationPropertyName> {

296

297

/**

298

* Create a ConfigurationPropertyName from the specified string

299

* @param name the source name (must not be null)

300

* @return a ConfigurationPropertyName instance or null if the name is not valid

301

*/

302

public static ConfigurationPropertyName of(String name);

303

304

/**

305

* Return if the given string is a valid ConfigurationPropertyName

306

* @param name the name to check

307

* @return true if the name is valid

308

*/

309

public static boolean isValid(CharSequence name);

310

311

/**

312

* Return a new ConfigurationPropertyName by appending the given elements

313

* @param elements the elements to append

314

* @return a new ConfigurationPropertyName

315

*/

316

public ConfigurationPropertyName append(String elements);

317

318

/**

319

* Return the number of elements that make up the name

320

* @return the number of elements

321

*/

322

public int getNumberOfElements();

323

324

/**

325

* Return an element from the name

326

* @param elementIndex the element index

327

* @return the element

328

*/

329

public String getElement(int elementIndex, Form form);

330

}

331

```

332

333

**Usage Examples:**

334

335

```java

336

@Service

337

public class ConfigurationService {

338

339

private final Binder binder;

340

341

public ConfigurationService(Environment environment) {

342

this.binder = Binder.get(environment);

343

}

344

345

public <T> T bindConfiguration(String prefix, Class<T> configClass) {

346

return binder.bind(prefix, configClass)

347

.orElseThrow(() -> new IllegalStateException("Could not bind " + prefix));

348

}

349

350

public void validateConfiguration() {

351

// Bind database configuration

352

DatabaseConfig dbConfig = bindConfiguration("app.database", DatabaseConfig.class);

353

354

// Bind cache configuration with default fallback

355

CacheConfig cacheConfig = binder.bind("app.cache", Bindable.of(CacheConfig.class))

356

.orElse(new CacheConfig()); // Use default if not configured

357

}

358

}

359

```

360

361

### Constructor and Default Value Binding

362

363

Annotations for constructor-based binding and default values.

364

365

```java { .api }

366

/**

367

* Annotation that can be used to indicate which constructor to use when binding

368

* configuration properties

369

*/

370

@Target({ElementType.CONSTRUCTOR, ElementType.TYPE})

371

@Retention(RetentionPolicy.RUNTIME)

372

@Documented

373

public @interface ConstructorBinding {

374

}

375

376

/**

377

* Annotation that can be used to specify a default value when binding to an

378

* immutable property

379

*/

380

@Target({ElementType.PARAMETER})

381

@Retention(RetentionPolicy.RUNTIME)

382

@Documented

383

public @interface DefaultValue {

384

385

/**

386

* The default value of the property

387

* @return the default values

388

*/

389

String[] value();

390

}

391

392

/**

393

* Annotation that can be used to specify the name when binding to an immutable property

394

*/

395

@Target({ElementType.PARAMETER})

396

@Retention(RetentionPolicy.RUNTIME)

397

@Documented

398

public @interface Name {

399

400

/**

401

* The name of the property to bind to

402

* @return the property name

403

*/

404

String value();

405

}

406

```

407

408

**Usage Examples:**

409

410

```java

411

// Constructor-based binding for immutable configuration

412

@ConfigurationProperties("server")

413

@ConstructorBinding

414

public class ServerProperties {

415

416

private final String host;

417

private final int port;

418

private final Duration timeout;

419

private final List<String> allowedOrigins;

420

421

public ServerProperties(@Name("host") @DefaultValue("localhost") String host,

422

@Name("port") @DefaultValue("8080") int port,

423

@DefaultValue("30s") Duration timeout,

424

@Name("allowed-origins") List<String> allowedOrigins) {

425

this.host = host;

426

this.port = port;

427

this.timeout = timeout;

428

this.allowedOrigins = allowedOrigins != null ? allowedOrigins : Collections.emptyList();

429

}

430

431

public String getHost() { return host; }

432

public int getPort() { return port; }

433

public Duration getTimeout() { return timeout; }

434

public List<String> getAllowedOrigins() { return allowedOrigins; }

435

}

436

```

437

438

### Property Validation and Error Handling

439

440

Handlers for property binding validation and error management.

441

442

```java { .api }

443

/**

444

* Callback interface that can be used to handle additional logic during element binding

445

*/

446

public interface BindHandler {

447

448

/**

449

* Handle the start of a bind operation for the given name and target

450

* @param name the name of the element being bound

451

* @param target the item being bound

452

* @param context the bind context

453

* @return the bound value or null

454

*/

455

default <T> Bindable<T> onStart(ConfigurationPropertyName name, Bindable<T> target, BindContext context) {

456

return target;

457

}

458

459

/**

460

* Handle a successful bind of an element

461

* @param name the name of the element being bound

462

* @param target the item being bound

463

* @param context the bind context

464

* @param result the bound result (may be null)

465

* @return the actual result that should be used (may be null)

466

*/

467

default Object onSuccess(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Object result) {

468

return result;

469

}

470

471

/**

472

* Handle a bind failure

473

* @param name the name of the element being bound

474

* @param target the item being bound

475

* @param context the bind context

476

* @param error the bind error

477

* @return the bound value or null if no recovery is possible

478

*/

479

default Object onFailure(ConfigurationPropertyName name, Bindable<?> target, BindContext context, Exception error)

480

throws Exception {

481

throw error;

482

}

483

}

484

485

/**

486

* BindHandler to enforce that all configuration properties are consumed when binding

487

*/

488

public class NoUnboundElementsBindHandler implements BindHandler {

489

490

/**

491

* Create a new NoUnboundElementsBindHandler instance

492

*/

493

public NoUnboundElementsBindHandler();

494

495

/**

496

* Create a new NoUnboundElementsBindHandler that delegates to the specified parent handler

497

* @param parent the parent handler

498

*/

499

public NoUnboundElementsBindHandler(BindHandler parent);

500

}

501

502

/**

503

* BindHandler that can be used to ignore binding errors

504

*/

505

public class IgnoreErrorsBindHandler implements BindHandler {

506

507

/**

508

* Create a new IgnoreErrorsBindHandler instance

509

*/

510

public IgnoreErrorsBindHandler();

511

512

/**

513

* Create a new IgnoreErrorsBindHandler that delegates to the specified parent handler

514

* @param parent the parent handler

515

*/

516

public IgnoreErrorsBindHandler(BindHandler parent);

517

}

518

519

/**

520

* BindHandler to apply JSR-303 style validation to bound results

521

*/

522

public class ValidationBindHandler implements BindHandler {

523

524

/**

525

* Create a new ValidationBindHandler using the default JSR-303 validator

526

*/

527

public ValidationBindHandler();

528

529

/**

530

* Create a new ValidationBindHandler using the given validator

531

* @param validator the validator to use

532

*/

533

public ValidationBindHandler(Validator validator);

534

}

535

```

536

537

### Property Mapping Utilities

538

539

Utilities for mapping and transforming properties during binding.

540

541

```java { .api }

542

/**

543

* Utility that can be used to map values from one object to another

544

*/

545

public final class PropertyMapper {

546

547

/**

548

* Return a new PropertyMapper instance

549

* @return new PropertyMapper instance

550

*/

551

public static PropertyMapper get();

552

553

/**

554

* Return a new PropertyMapper that will always apply non-null values when mapping

555

* @return new PropertyMapper that applies non-null values

556

*/

557

public PropertyMapper alwaysApplyingWhenNonNull();

558

559

/**

560

* Supply a source value that will be mapped

561

* @param value the value (may be null)

562

* @return a property source

563

*/

564

public <T> Source<T> from(T value);

565

566

/**

567

* Supply a source value from a supplier that will be mapped

568

* @param supplier the value supplier (may return null)

569

* @return a property source

570

*/

571

public <T> Source<T> from(Supplier<T> supplier);

572

573

/**

574

* A source that is in the process of being mapped

575

*/

576

public static final class Source<T> {

577

578

/**

579

* Apply a condition that must be met for the mapping to be applied

580

* @param condition the condition that must be met

581

* @return a filtered source

582

*/

583

public Source<T> when(Predicate<T> condition);

584

585

/**

586

* Apply the mapping when the value is not null

587

* @return a filtered source that won't map null values

588

*/

589

public Source<T> whenNonNull();

590

591

/**

592

* Apply the mapping using the given consumer

593

* @param consumer the consumer to apply the mapping

594

*/

595

public void to(Consumer<T> consumer);

596

597

/**

598

* Apply the mapping to the given setter

599

* @param setter the setter to apply

600

*/

601

public <R> void to(Function<T, R> mapper, Consumer<R> consumer);

602

}

603

}

604

```

605

606

**Usage Examples:**

607

608

```java

609

@Component

610

public class ConfigurationMapper {

611

612

public void configureHttpClient(HttpClientProperties source, HttpClient.Builder target) {

613

PropertyMapper map = PropertyMapper.get().alwaysApplyingWhenNonNull();

614

615

map.from(source.getTimeout()).to(target::timeout);

616

map.from(source.getMaxConnections()).to(target::maxConnections);

617

map.from(source.isFollowRedirects()).to(target::followRedirects);

618

map.from(source.getProxyHost()).whenNonNull().to(target::proxy);

619

620

// Conditional mapping

621

map.from(source.getRetryCount())

622

.when(count -> count > 0)

623

.to(target::retryPolicy);

624

}

625

}

626

```

627

628

### Environment Post-Processing

629

630

Interface for post-processing the environment before application context refresh.

631

632

```java { .api }

633

/**

634

* Allows for customization of the application's Environment prior to the application

635

* context being refreshed

636

*/

637

@FunctionalInterface

638

public interface EnvironmentPostProcessor {

639

640

/**

641

* Post-process the given ConfigurableEnvironment after all property sources have been loaded

642

* @param environment the environment to post-process

643

* @param application the application to which the environment belongs

644

*/

645

void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);

646

}

647

648

/**

649

* Strategy interface for loading property sources from resources

650

*/

651

public interface PropertySourceLoader {

652

653

/**

654

* Returns the file extensions that this loader supports (excluding the '.')

655

* @return the file extensions

656

*/

657

String[] getFileExtensions();

658

659

/**

660

* Load the resource into one or more property sources

661

* @param name the root name of the property source. If multiple documents are loaded

662

* an additional suffix should be added to the name for each source loaded

663

* @param resource the resource to load

664

* @return a list property sources

665

* @throws IOException if the resource cannot be loaded

666

*/

667

List<PropertySource<?>> load(String name, Resource resource) throws IOException;

668

}

669

```

670

671

**Usage Examples:**

672

673

```java

674

// Custom environment post-processor

675

public class CustomEnvironmentPostProcessor implements EnvironmentPostProcessor {

676

677

@Override

678

public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {

679

// Add custom property sources based on environment conditions

680

if (environment.acceptsProfiles(Profiles.of("dev"))) {

681

Properties devProps = new Properties();

682

devProps.put("logging.level.com.example", "DEBUG");

683

devProps.put("spring.jpa.show-sql", "true");

684

685

PropertiesPropertySource devPropertySource = new PropertiesPropertySource("devProperties", devProps);

686

environment.getPropertySources().addLast(devPropertySource);

687

}

688

}

689

}

690

691

// Custom property source loader for YAML files

692

public class YamlPropertySourceLoader implements PropertySourceLoader {

693

694

@Override

695

public String[] getFileExtensions() {

696

return new String[]{"yml", "yaml"};

697

}

698

699

@Override

700

public List<PropertySource<?>> load(String name, Resource resource) throws IOException {

701

if (resource.exists()) {

702

List<PropertySource<?>> propertySources = new ArrayList<>();

703

// Load YAML and convert to PropertySource

704

// Implementation details...

705

return propertySources;

706

}

707

return Collections.emptyList();

708

}

709

}

710

711

// Register in META-INF/spring.factories:

712

// org.springframework.boot.env.EnvironmentPostProcessor=\

713

// com.example.CustomEnvironmentPostProcessor

714

// org.springframework.boot.env.PropertySourceLoader=\

715

// com.example.YamlPropertySourceLoader

716

```

717

718

## Configuration Property Sources

719

720

```java { .api }

721

/**

722

* ConfigurationPropertySource backed by a Map

723

*/

724

public class MapConfigurationPropertySource implements IterableConfigurationPropertySource {

725

726

/**

727

* Create a new MapConfigurationPropertySource instance

728

* @param name the name of the property source

729

* @param source the underlying map source

730

*/

731

public MapConfigurationPropertySource(String name, Map<?, ?> source);

732

733

/**

734

* Convenience method to create a MapConfigurationPropertySource from a Map with

735

* relaxed names support

736

* @param source the source map

737

* @return the property source

738

*/

739

public static MapConfigurationPropertySource from(Map<String, Object> source);

740

}

741

```