Spring Boot Starter architecture
This page provides a technical overview of the Atoti What-If Spring Boot Starter architecture for developers who need to understand how auto-configuration works.
Module structure
The starter is split into three modules:
| Module | Artifact ID | Description |
|---|---|---|
| Library | atoti-what-if-lib |
Core business logic, interfaces, and implementations |
| Configuration | atoti-what-if-config |
Auto-configuration classes and property bindings |
| Starter | atoti-what-if-spring-boot-starter |
Dependency aggregator that pulls in lib and config |
The starter module contains no code. It serves as a single dependency that transitively includes the library and configuration modules.
Auto-configuration classes
Each auto-configuration class is responsible for a specific functional area:
| Class | Beans Created | Condition |
|---|---|---|
WhatIfCoreConfig |
DatabaseSimulationEngine, IUniqueIdGenerator |
Always active |
WhatIfPersistenceConfig |
SessionFactory, ISimulationPersistenceManager |
IWhatIfPersistenceProperties bean present |
WhatIfSecurityConfig |
IDatabaseSimulationsSecurityManager |
Based on security.type property |
WhatIfWorkflowConfig |
IDatabaseSimulationsWorkflow |
Always active |
WhatIfRestConfig |
DatabaseSimulationsRestService, exception handler |
Always active |
WhatIfDistributionConfig |
RestDistributedDatabaseService, address/auth suppliers |
distribution.enabled: true |
Bean creation order
Beans are created in dependency order:
┌─────────────────────────┐
│ IWhatIfPersistence │ (provided by application)
│ Properties │
└───────────┬─────────────┘
│
▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ SessionFactory │ │ DatabaseSimulation │
│ (Persistence) │ │ Engine │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
▼ │
┌─────────────────────────┐ │
│ ISimulationPersistence │ │
│ Manager │ │
└───────────┬─────────────┘ │
│ │
▼ │
┌─────────────────────────┐ │
│ IDatabaseSimulations │ │
│ SecurityManager │ │
└───────────┬─────────────┘ │
│ │
▼ ▼
┌─────────────────────────────────────────────┐
│ IDatabaseSimulationsWorkflow │
└───────────────────┬─────────────────────────┘
│
▼
┌─────────────────────────────────────────────┐
│ DatabaseSimulationsRestService │
└─────────────────────────────────────────────┘
The SessionFactory bean (named whatIfSessionFactory) can be overridden independently of ISimulationPersistenceManager. It includes destroyMethod = "close" to ensure proper resource cleanup on application shutdown.
Conditional annotations
The auto-configuration uses Spring Boot conditional annotations:
@ConditionalOnMissingBean
All beans use @ConditionalOnMissingBean, allowing application-defined beans to take precedence:
@Bean
@ConditionalOnMissingBean
public IUniqueIdGenerator idGenerator() {
return new IncrementalUniqueIdGenerator();
}
@ConditionalOnProperty
Property-based conditions control feature activation:
@ConditionalOnProperty(
prefix = "atoti.what-if",
name = "distribution.enabled",
havingValue = "true")
public class WhatIfDistributionConfig { ... }
@ConditionalOnWhatIfEnabled
A custom conditional annotation that gates all What-If beans on the atoti.what-if.enable property. It combines two condition classes for different Spring lifecycle phases:
ConfigurationEnabledWhatIf— evaluates duringPARSE_CONFIGURATIONphase (applies to@Configurationclasses)BeanEnabledWhatIf— evaluates duringREGISTER_BEANphase (applies to@Beanmethods)
@ConditionalOnWhatIfEnabled
@Configuration
public class WhatIfCoreConfig {
// Beans here are only registered when atoti.what-if.enable is true (default)
}
Setting atoti.what-if.enable: false disables all auto-configuration classes annotated with @ConditionalOnWhatIfEnabled.
@ConditionalOnWhatIfDistributionEnabled
A custom conditional annotation that gates Atoti What-If distribution beans on the atoti.what-if.distribution.enabled property. Like @ConditionalOnWhatIfEnabled, it combines two condition classes for different Spring lifecycle phases:
ConfigurationEnabledWhatIfDistribution— evaluates duringPARSE_CONFIGURATIONphase (applies to@Configurationclasses)BeanEnabledWhatIfDistribution— evaluates duringREGISTER_BEANphase (applies to@Beanmethods)
Unlike @ConditionalOnWhatIfEnabled, this annotation does not default to enabled. When the property is absent, distribution beans are not registered.
The annotation is typically used alongside @ConditionalOnWhatIfEnabled on WhatIfDistributionConfig:
@ConditionalOnWhatIfEnabled
@ConditionalOnWhatIfDistributionEnabled
@Configuration
public class WhatIfDistributionConfig {
// Beans here require both atoti.what-if.enable (default: true)
// AND atoti.what-if.distribution.enabled=true
}
Setting atoti.what-if.distribution.enabled: true activates distribution features. Defaults to false.
Property binding
Properties are bound using @ConfigurationProperties:
@ConfigurationProperties(prefix = "atoti.what-if")
public class WhatIfProperties {
private final boolean enable;
private final Security security;
private final Distribution distribution;
// ...
}
Nested records provide type-safe configuration:
public record Security(SecurityType type, boolean useBranchPermissions) {
public Security(
@DefaultValue("SPRING") SecurityType type,
@DefaultValue("true") boolean useBranchPermissions) {
this.type = type;
this.useBranchPermissions = useBranchPermissions;
}
}
Extension points
Overriding beans
Define a bean of the same type to override auto-configuration:
@Bean
public IUniqueIdGenerator customIdGenerator() {
return new MyIdGenerator(); // Takes precedence
}
See How to customize auto-configured beans for detailed examples.
Required application beans
The starter requires these beans from your application:
| Bean | Purpose |
|---|---|
IDatabaseService |
Provided by Atoti Server for datastore operations |
IWhatIfPersistenceProperties |
Provides Hibernate configuration for persistence |
Without these beans, the corresponding auto-configuration is skipped or fails.