Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt

Use this file to discover all available pages before exploring further.

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:
ModuleArtifact IDDescription
Libraryatoti-what-if-libCore business logic, interfaces, and implementations
Configurationatoti-what-if-configAuto-configuration classes and property bindings
Starteratoti-what-if-spring-boot-starterDependency 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:
ClassBeans CreatedCondition
WhatIfCoreConfigDatabaseSimulationEngine, IUniqueIdGeneratorAlways active
WhatIfPersistenceConfigSessionFactory, ISimulationPersistenceManagerIWhatIfPersistenceProperties bean present
WhatIfSecurityConfigIDatabaseSimulationsSecurityManagerBased on security.type property
WhatIfWorkflowConfigIDatabaseSimulationsWorkflowAlways active
WhatIfRestConfigDatabaseSimulationsRestService, exception handlerAlways active
WhatIfDistributionConfigRestDistributedDatabaseService, address/auth suppliersdistribution.enabled: true

Bean creation order

Beans are created in dependency order: 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 during PARSE_CONFIGURATION phase (applies to @Configuration classes)
  • BeanEnabledWhatIf — evaluates during REGISTER_BEAN phase (applies to @Bean methods)
@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 during PARSE_CONFIGURATION phase (applies to @Configuration classes)
  • BeanEnabledWhatIfDistribution — evaluates during REGISTER_BEAN phase (applies to @Bean methods)
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:
BeanPurpose
IDatabaseServiceProvided by Atoti Server for datastore operations
IWhatIfPersistencePropertiesProvides Hibernate configuration for persistence
Without these beans, the corresponding auto-configuration is skipped or fails.