or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cache-configuration.mdconditional-configuration.mdcore-autoconfiguration.mddata-configuration.mdindex.mdjson-configuration.mdmessaging-configuration.mdsecurity-configuration.mdservice-connections.mdtemplate-configuration.mdweb-configuration.md

conditional-configuration.mddocs/

0

# Conditional Configuration

1

2

Spring Boot's conditional configuration system provides sophisticated annotations that determine when auto-configurations should be applied based on various runtime conditions including classpath contents, bean presence, properties, and environment characteristics.

3

4

## Capabilities

5

6

### Class-Based Conditions

7

8

Conditional annotations that evaluate based on the presence or absence of classes on the classpath.

9

10

```java { .api }

11

/**

12

* Matches when all specified classes are present on the classpath

13

* Most commonly used conditional annotation in auto-configurations

14

*/

15

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

16

@Retention(RetentionPolicy.RUNTIME)

17

@Documented

18

@Conditional(OnClassCondition.class)

19

public @interface ConditionalOnClass {

20

/**

21

* Classes that must be present on the classpath

22

* @return array of required classes

23

*/

24

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

25

26

/**

27

* Class names that must be present (alternative to value for classes not on current classpath)

28

* @return array of required class names

29

*/

30

String[] name() default {};

31

}

32

33

/**

34

* Matches when none of the specified classes are present on the classpath

35

* Used to disable configurations when competing libraries are present

36

*/

37

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

38

@Retention(RetentionPolicy.RUNTIME)

39

@Documented

40

@Conditional(OnClassCondition.class)

41

public @interface ConditionalOnMissingClass {

42

/**

43

* Classes that must not be present on the classpath

44

* @return array of classes that should be absent

45

*/

46

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

47

48

/**

49

* Class names that must not be present

50

* @return array of class names that should be absent

51

*/

52

String[] name() default {};

53

}

54

```

55

56

**Usage Examples:**

57

58

```java

59

@AutoConfiguration

60

@ConditionalOnClass({DataSource.class, JdbcTemplate.class})

61

public class JdbcTemplateAutoConfiguration {

62

// Only applies when both DataSource and JdbcTemplate are on classpath

63

}

64

65

@AutoConfiguration

66

@ConditionalOnClass(name = "com.fasterxml.jackson.databind.ObjectMapper")

67

@ConditionalOnMissingClass("com.google.gson.Gson")

68

public class JacksonAutoConfiguration {

69

// Applies when Jackson is present but Gson is not

70

}

71

```

72

73

### Bean-Based Conditions

74

75

Conditional annotations that evaluate based on the presence, absence, or characteristics of beans in the application context.

76

77

```java { .api }

78

/**

79

* Matches when specified beans are present in the application context

80

* Useful for ensuring dependencies are available

81

*/

82

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

83

@Retention(RetentionPolicy.RUNTIME)

84

@Documented

85

@Conditional(OnBeanCondition.class)

86

public @interface ConditionalOnBean {

87

/**

88

* Bean classes that must be present

89

* @return array of required bean classes

90

*/

91

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

92

93

/**

94

* Bean type names that must be present

95

* @return array of required bean type names

96

*/

97

String[] type() default {};

98

99

/**

100

* Bean names that must be present

101

* @return array of required bean names

102

*/

103

String[] name() default {};

104

105

/**

106

* Strategy for searching beans

107

* @return search strategy

108

*/

109

SearchStrategy search() default SearchStrategy.ALL;

110

111

/**

112

* Additional annotation that must be present on the beans

113

* @return annotation class

114

*/

115

Class<? extends Annotation> annotation() default Annotation.class;

116

117

/**

118

* Whether to match if any of the conditions match (OR) or all must match (AND)

119

* @return parameterized container annotation

120

*/

121

Class<?> parameterizedContainer() default Object.class;

122

}

123

124

/**

125

* Matches when specified beans are not present in the application context

126

* Most commonly used to provide default beans when user hasn't defined their own

127

*/

128

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

129

@Retention(RetentionPolicy.RUNTIME)

130

@Documented

131

@Conditional(OnBeanCondition.class)

132

public @interface ConditionalOnMissingBean {

133

/**

134

* Bean classes that must not be present

135

* @return array of bean classes that should be absent

136

*/

137

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

138

139

/**

140

* Bean type names that must not be present

141

* @return array of bean type names that should be absent

142

*/

143

String[] type() default {};

144

145

/**

146

* Bean names that must not be present

147

* @return array of bean names that should be absent

148

*/

149

String[] name() default {};

150

151

/**

152

* Classes to ignore when checking for missing beans

153

* @return array of classes to ignore

154

*/

155

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

156

157

/**

158

* Bean types to ignore when checking for missing beans

159

* @return array of ignored bean types

160

*/

161

String[] ignoredType() default {};

162

163

/**

164

* Strategy for searching beans

165

* @return search strategy

166

*/

167

SearchStrategy search() default SearchStrategy.ALL;

168

169

/**

170

* Additional annotation that must be present on the beans

171

* @return annotation class

172

*/

173

Class<? extends Annotation> annotation() default Annotation.class;

174

175

/**

176

* Whether to match if any of the conditions match (OR) or all must match (AND)

177

* @return parameterized container annotation

178

*/

179

Class<?> parameterizedContainer() default Object.class;

180

}

181

182

/**

183

* Matches when there is exactly one primary bean of the specified type

184

* Used when multiple beans exist but only one is marked as primary

185

*/

186

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

187

@Retention(RetentionPolicy.RUNTIME)

188

@Documented

189

@Conditional(OnBeanCondition.class)

190

public @interface ConditionalOnSingleCandidate {

191

/**

192

* Bean class for which there should be a single candidate

193

* @return the bean class

194

*/

195

Class<?> value() default Object.class;

196

197

/**

198

* Bean type for which there should be a single candidate

199

* @return the bean type name

200

*/

201

String type() default "";

202

203

/**

204

* Strategy for searching beans

205

* @return search strategy

206

*/

207

SearchStrategy search() default SearchStrategy.ALL;

208

}

209

```

210

211

**Usage Examples:**

212

213

```java

214

@Bean

215

@ConditionalOnMissingBean(DataSource.class)

216

public DataSource dataSource() {

217

// Creates default DataSource only if user hasn't defined one

218

return new HikariDataSource();

219

}

220

221

@Bean

222

@ConditionalOnBean(DataSource.class)

223

public JdbcTemplate jdbcTemplate(DataSource dataSource) {

224

// Creates JdbcTemplate only when DataSource bean exists

225

return new JdbcTemplate(dataSource);

226

}

227

228

@AutoConfiguration

229

@ConditionalOnSingleCandidate(DataSource.class)

230

public class SingleDataSourceConfiguration {

231

// Applies when there's exactly one primary DataSource bean

232

}

233

```

234

235

### Property-Based Conditions

236

237

Conditional annotations that evaluate based on application properties and their values.

238

239

```java { .api }

240

/**

241

* Matches based on the presence and value of a single property

242

* Most flexible property-based condition

243

*/

244

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

245

@Retention(RetentionPolicy.RUNTIME)

246

@Documented

247

@Conditional(OnPropertyCondition.class)

248

public @interface ConditionalOnProperty {

249

/**

250

* Property names to check (alternative to name)

251

* @return array of property names

252

*/

253

String[] value() default {};

254

255

/**

256

* Prefix to apply to property names

257

* @return property prefix

258

*/

259

String prefix() default "";

260

261

/**

262

* Property names to check

263

* @return array of property names

264

*/

265

String[] name() default {};

266

267

/**

268

* Expected value for the property

269

* @return expected property value

270

*/

271

String havingValue() default "";

272

273

/**

274

* Whether condition matches if property is missing

275

* @return true if condition should match when property is missing

276

*/

277

boolean matchIfMissing() default false;

278

279

/**

280

* Relaxed binding for property names

281

* @return true to enable relaxed binding

282

*/

283

boolean relaxedNames() default true;

284

}

285

286

/**

287

* Matches when all specified properties have expected values

288

* Used for multiple property conditions that must all be true

289

*/

290

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

291

@Retention(RetentionPolicy.RUNTIME)

292

@Documented

293

@Conditional(OnPropertyCondition.class)

294

public @interface ConditionalOnProperties {

295

/**

296

* Properties that must all match their expected values

297

* @return array of ConditionalOnProperty annotations

298

*/

299

ConditionalOnProperty[] value();

300

}

301

302

/**

303

* Matches when boolean properties have expected values

304

* Simplified version for boolean property checks

305

*/

306

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

307

@Retention(RetentionPolicy.RUNTIME)

308

@Documented

309

@Conditional(OnPropertyCondition.class)

310

public @interface ConditionalOnBooleanProperty {

311

/**

312

* Property name to check

313

* @return property name

314

*/

315

String name();

316

317

/**

318

* Prefix to apply to property name

319

* @return property prefix

320

*/

321

String prefix() default "";

322

323

/**

324

* Expected boolean value

325

* @return expected boolean value

326

*/

327

boolean value() default true;

328

329

/**

330

* Whether condition matches if property is missing

331

* @return true if condition should match when property is missing

332

*/

333

boolean matchIfMissing() default false;

334

}

335

```

336

337

**Usage Examples:**

338

339

```java

340

@AutoConfiguration

341

@ConditionalOnProperty(prefix = "app.features", name = "advanced", havingValue = "true")

342

public class AdvancedFeaturesAutoConfiguration {

343

// Only applies when app.features.advanced=true

344

}

345

346

@Bean

347

@ConditionalOnProperty(value = "spring.datasource.url", matchIfMissing = false)

348

public DataSource customDataSource(@Value("${spring.datasource.url}") String url) {

349

// Creates bean only when spring.datasource.url property is present

350

}

351

352

@AutoConfiguration

353

@ConditionalOnProperties({

354

@ConditionalOnProperty(name = "feature.enabled", havingValue = "true"),

355

@ConditionalOnProperty(name = "feature.mode", havingValue = "advanced")

356

})

357

public class ConditionalFeatureConfiguration {

358

// Applies when both properties have expected values

359

}

360

```

361

362

### Environment and Platform Conditions

363

364

Conditional annotations that evaluate based on environment characteristics, deployment context, and platform detection.

365

366

```java { .api }

367

/**

368

* Matches when application is running on a specific cloud platform

369

* Automatically detects cloud platforms based on environment variables and system properties

370

*/

371

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

372

@Retention(RetentionPolicy.RUNTIME)

373

@Documented

374

@Conditional(OnCloudPlatformCondition.class)

375

public @interface ConditionalOnCloudPlatform {

376

/**

377

* Cloud platform that must be detected

378

* @return required cloud platform

379

*/

380

CloudPlatform value();

381

}

382

383

/**

384

* Matches when application is running on a specific Java version or range

385

* Useful for enabling features that require specific Java versions

386

*/

387

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

388

@Retention(RetentionPolicy.RUNTIME)

389

@Documented

390

@Conditional(OnJavaCondition.class)

391

public @interface ConditionalOnJava {

392

/**

393

* Java version range specification

394

* @return Java version range

395

*/

396

Range range() default Range.EQUAL_OR_NEWER;

397

398

/**

399

* Specific Java version to match against

400

* @return Java version

401

*/

402

JavaVersion value();

403

404

enum Range {

405

EQUAL_OR_NEWER, OLDER_THAN

406

}

407

}

408

409

/**

410

* Matches when application is deployed as a WAR file

411

* Used to enable WAR-specific configurations

412

*/

413

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

414

@Retention(RetentionPolicy.RUNTIME)

415

@Documented

416

@Conditional(OnWarDeploymentCondition.class)

417

public @interface ConditionalOnWarDeployment {

418

}

419

420

/**

421

* Matches when application is NOT deployed as a WAR file

422

* Used for embedded server configurations

423

*/

424

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

425

@Retention(RetentionPolicy.RUNTIME)

426

@Documented

427

@Conditional(OnWarDeploymentCondition.class)

428

public @interface ConditionalOnNotWarDeployment {

429

}

430

431

/**

432

* Matches based on web application type (servlet, reactive, or none)

433

* Essential for web-specific auto-configurations

434

*/

435

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

436

@Retention(RetentionPolicy.RUNTIME)

437

@Documented

438

@Conditional(OnWebApplicationCondition.class)

439

public @interface ConditionalOnWebApplication {

440

/**

441

* Type of web application required

442

* @return web application type

443

*/

444

Type type() default Type.ANY;

445

446

enum Type {

447

ANY, SERVLET, REACTIVE

448

}

449

}

450

451

/**

452

* Matches when application is not a web application

453

* Used for non-web configurations

454

*/

455

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

456

@Retention(RetentionPolicy.RUNTIME)

457

@Documented

458

@Conditional(OnNotWebApplicationCondition.class)

459

public @interface ConditionalOnNotWebApplication {

460

}

461

```

462

463

**Usage Examples:**

464

465

```java

466

@AutoConfiguration

467

@ConditionalOnCloudPlatform(CloudPlatform.KUBERNETES)

468

public class KubernetesSpecificConfiguration {

469

// Only applies when running on Kubernetes

470

}

471

472

@Bean

473

@ConditionalOnJava(value = JavaVersion.SEVENTEEN, range = Range.EQUAL_OR_NEWER)

474

public ModernJavaService modernJavaService() {

475

// Only creates bean on Java 17 or newer

476

}

477

478

@AutoConfiguration

479

@ConditionalOnWebApplication(type = Type.SERVLET)

480

@ConditionalOnNotWarDeployment

481

public class EmbeddedServletConfiguration {

482

// Applies to servlet web apps not deployed as WAR

483

}

484

```

485

486

### Resource and Expression Conditions

487

488

Advanced conditional annotations for specific resource requirements and custom logic.

489

490

```java { .api }

491

/**

492

* Matches when specified resources are available on the classpath

493

* Useful for configuration files or templates

494

*/

495

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

496

@Retention(RetentionPolicy.RUNTIME)

497

@Documented

498

@Conditional(OnResourceCondition.class)

499

public @interface ConditionalOnResource {

500

/**

501

* Resources that must be present on the classpath

502

* @return array of resource paths

503

*/

504

String[] resources() default {};

505

}

506

507

/**

508

* Matches based on SpEL (Spring Expression Language) evaluation

509

* Provides maximum flexibility for complex conditions

510

*/

511

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

512

@Retention(RetentionPolicy.RUNTIME)

513

@Documented

514

@Conditional(OnExpressionCondition.class)

515

public @interface ConditionalOnExpression {

516

/**

517

* SpEL expression that must evaluate to true

518

* @return Spring expression

519

*/

520

String value();

521

}

522

523

/**

524

* Matches when JNDI is available and optionally when specific JNDI locations exist

525

* Used for enterprise application server configurations

526

*/

527

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

528

@Retention(RetentionPolicy.RUNTIME)

529

@Documented

530

@Conditional(OnJndiCondition.class)

531

public @interface ConditionalOnJndi {

532

/**

533

* JNDI locations that must be available

534

* @return array of JNDI locations

535

*/

536

String[] value() default {};

537

}

538

539

/**

540

* Matches based on threading model (virtual threads support)

541

* Used for Java 21+ virtual threads features

542

*/

543

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

544

@Retention(RetentionPolicy.RUNTIME)

545

@Documented

546

@Conditional(OnThreadingCondition.class)

547

public @interface ConditionalOnThreading {

548

/**

549

* Threading model required

550

* @return threading model

551

*/

552

Threading value();

553

554

enum Threading {

555

PLATFORM, VIRTUAL

556

}

557

}

558

```

559

560

**Usage Examples:**

561

562

```java

563

@Bean

564

@ConditionalOnResource(resources = "classpath:templates/custom-error.html")

565

public CustomErrorViewResolver customErrorViewResolver() {

566

// Only creates bean if custom error template exists

567

}

568

569

@AutoConfiguration

570

@ConditionalOnExpression("${app.features.experimental:false} && ${app.env} == 'development'")

571

public class ExperimentalFeaturesConfiguration {

572

// Complex condition using SpEL

573

}

574

575

@Bean

576

@ConditionalOnJndi("java:comp/env/jdbc/MyDataSource")

577

public DataSource jndiDataSource() {

578

// Creates bean only if JNDI DataSource is available

579

}

580

```

581

582

## Types

583

584

### Condition Support Types

585

586

```java { .api }

587

/**

588

* Search strategy for bean conditions

589

*/

590

public enum SearchStrategy {

591

/**

592

* Search only the current application context

593

*/

594

CURRENT,

595

596

/**

597

* Search the current application context and all ancestors

598

*/

599

ANCESTORS,

600

601

/**

602

* Search the current application context and all ancestors and descendants

603

*/

604

ALL

605

}

606

607

/**

608

* Supported cloud platforms for automatic detection

609

*/

610

public enum CloudPlatform {

611

NONE(""),

612

CLOUD_FOUNDRY("Cloud Foundry"),

613

HEROKU("Heroku"),

614

SAP("SAP Cloud Platform"),

615

KUBERNETES("Kubernetes"),

616

AZURE("Microsoft Azure"),

617

AWS("Amazon Web Services"),

618

GOOGLE_CLOUD("Google Cloud Platform");

619

620

private final String name;

621

622

public String getName();

623

public boolean isActive(Environment environment);

624

}

625

626

/**

627

* Java version enumeration for version-based conditions

628

*/

629

public enum JavaVersion {

630

EIGHT(8, "1.8", "java.util.Optional"),

631

NINE(9, "9", "java.lang.Runtime$Version"),

632

TEN(10, "10", "java.util.List.copyOf"),

633

ELEVEN(11, "11", "java.lang.String.strip"),

634

TWELVE(12, "12", "java.lang.String.indent"),

635

THIRTEEN(13, "13", "java.lang.String.formatted"),

636

FOURTEEN(14, "14", "java.lang.Record"),

637

FIFTEEN(15, "15", "java.lang.CharSequence.isEmpty"),

638

SIXTEEN(16, "16", "java.lang.Record.getRecordComponents"),

639

SEVENTEEN(17, "17", "java.util.random.RandomGenerator"),

640

EIGHTEEN(18, "18", "java.lang.String.stripIndent"),

641

NINETEEN(19, "19", "java.util.concurrent.StructuredTaskScope"),

642

TWENTY(20, "20", "java.lang.foreign.Arena"),

643

TWENTY_ONE(21, "21", "java.lang.Thread.ofVirtual");

644

645

public boolean isEqualOrNewerThan(JavaVersion version);

646

public boolean isOlderThan(JavaVersion version);

647

}

648

```

649

650

### Condition Evaluation Types

651

652

```java { .api }

653

/**

654

* Result of a condition evaluation

655

*/

656

public class ConditionOutcome {

657

658

/**

659

* Create a matching outcome with a message

660

* @param match whether the condition matches

661

* @param message descriptive message

662

*/

663

public ConditionOutcome(boolean match, String message);

664

665

/**

666

* Create a matching outcome with a ConditionMessage

667

* @param match whether the condition matches

668

* @param message condition message

669

*/

670

public ConditionOutcome(boolean match, ConditionMessage message);

671

672

/**

673

* Whether the condition matches

674

* @return true if condition matches

675

*/

676

public boolean isMatch();

677

678

/**

679

* Get the outcome message

680

* @return condition message

681

*/

682

public String getMessage();

683

684

/**

685

* Create a matching outcome with no message

686

* @return matching ConditionOutcome

687

*/

688

public static ConditionOutcome match();

689

690

/**

691

* Create a non-matching outcome with no message

692

* @return non-matching ConditionOutcome

693

*/

694

public static ConditionOutcome noMatch();

695

}

696

697

/**

698

* Builder for condition messages

699

*/

700

public final class ConditionMessage {

701

702

/**

703

* Create an empty condition message

704

* @return empty ConditionMessage

705

*/

706

public static ConditionMessage empty();

707

708

/**

709

* Create a condition message with formatted text

710

* @param message message template

711

* @param args message arguments

712

* @return ConditionMessage instance

713

*/

714

public static ConditionMessage of(String message, Object... args);

715

716

/**

717

* Add additional condition information

718

* @param condition condition name

719

* @param args condition arguments

720

* @return ConditionMessage with additional condition

721

*/

722

public ConditionMessage andCondition(String condition, Object... args);

723

724

/**

725

* Add reason for the condition result

726

* @param reason reason message

727

* @param args reason arguments

728

* @return ConditionMessage with reason

729

*/

730

public ConditionMessage because(String reason, Object... args);

731

}

732

```