Enterprise Java

Understanding Configuration Order in Spring Boot

Spring Boot simplifies application setup by providing a structured and opinionated configuration model. As applications evolve across different environments, it becomes important to understand how Spring Boot decides which configuration value should take precedence. Multiple configuration sources may define the same property, but Spring Boot resolves these conflicts through a predefined ordering strategy.

This article explains the configuration precedence in Spring Boot, examines its default ordering behaviour, and explores ways we can manually control configuration order using annotations and auto-configuration features.

1. How Spring Boot Loads and Initialises Beans

Before properties are applied, Spring Boot first builds the application context and ensures that the beans required by the application are discovered, registered, and initialised. Spring scans the application for components and configuration classes, creates BeanDefinition objects, and resolves dependencies so that beans are initialised in the correct order.

The ApplicationContext serves as the container that manages all beans. Behind the scenes, a BeanFactory (commonly DefaultListableBeanFactory) performs the work of storing bean definitions and creating instances when needed. Spring determines bean instantiation order based on dependency requirements. If Bean A relies on Bean B, then Bean B is initialized first, without needing explicit ordering instructions.

Example: Automatic Dependency-Based Ordering

@Configuration
public class BeanConfig {

    @Bean
    public FirstBean firstBean() {
        System.out.println("FirstBean initialized");
        return new FirstBean();
    }

    @Bean
    public SecondBean secondBean(FirstBean firstBean) {
        System.out.println("SecondBean initialized after FirstBean");
        return new SecondBean();
    }
}

Expected Output

FirstBean initialized
SecondBean initialized after FirstBean

Here, Spring automatically delays SecondBean initialization until FirstBean is ready. If beans do not depend on one another, Spring does not guarantee order.

Example: Unordered Initialization

@Configuration
public class IndependentBeanConfig {

    @Bean
    public AlphaBean alphaBean() {
        System.out.println("AlphaBean initialized");
        return new AlphaBean();
    }

    @Bean
    public BetaBean betaBean() {
        System.out.println("BetaBean initialized");
        return new BetaBean();
    }
}

Possible Output

AlphaBean initialized
BetaBean initialized

The order here may vary between executions or environments because no dependencies exist.

2. Controlling Order Using @Order Annotation

The @Order annotation gives us control over initialization order when more than one configuration or component influences the same system behaviour. It assigns priority to configuration classes or components where lower values indicate higher precedence.

@Configuration
@Order(1)
public class PrimaryConfig {
    public PrimaryConfig() {
        System.out.println("PrimaryConfig loaded first");
    }
}
@Configuration
@Order(2)
public class SecondaryConfig {

    public SecondaryConfig() {
        System.out.println("SecondaryConfig loaded second");
    }
}

Possible Output

PrimaryConfig loaded first
SecondaryConfig loaded second

This ensures correct ordering when sequence matters (e.g., security initialization before data services).

3. Managing Dependencies Using @DependsOn

In some cases, configuration must load in a specific sequence because one bean depends on another. To control that relationship, the @DependsOn annotation is used. When applied, it informs the Spring container that a particular bean must be fully initialized before the dependent bean is created.

@Configuration
public class CacheConfig {

    @Bean
    public CacheInitializer cacheInitializer() {
        System.out.println("Cache initialized");
        return new CacheInitializer();
    }
}
@Configuration
public class DataServiceConfig {

    @Bean
    @DependsOn("cacheInitializer")
    public DataService dataService() {
        System.out.println("DataService initialized after Cache");
        return new DataService();
    }
}

Here, DataService initialization is postponed until cacheInitializer has completed its setup, guaranteeing reliable startup behaviour.

Output

Cache initialized
DataService initialized after Cache

4. Auto-Configuration Order in Spring Boot

Spring Boot’s auto-configuration mechanism automatically sets up components based on the classes available on the classpath and existing user-defined beans. When multiple auto-configurations influence similar components, Spring Boot determines the order using annotation-based hints. Spring provides several ways to control the execution order of auto-configuration:

  • @AutoConfigureOrder: assigns a numeric priority (lower values = higher precedence)
  • @AutoConfigureBefore: ensures your configuration runs before another auto-configuration
  • @AutoConfigureAfter: ensures your configuration runs after another auto-configuration

Below is an example demonstrating all three annotations.

@Configuration
@AutoConfigureOrder(1) // High priority (lower number)
public class FrameworkAutoConfig {

    public FrameworkAutoConfig() {
        System.out.println("FrameworkAutoConfig initialized");
    }
}

CustomLoggingAutoConfig class loads before FrameworkAutoConfig.

@Configuration
@AutoConfigureBefore(FrameworkAutoConfig.class)
public class CustomLoggingAutoConfig {

    public CustomLoggingAutoConfig() {
        System.out.println("CustomLoggingAutoConfig initialized (Before FrameworkAutoConfig)");
    }
}

CustomMetricsAutoConfig class loads after FrameworkAutoConfig.

@Configuration
@AutoConfigureAfter(FrameworkAutoConfig.class)
public class CustomMetricsAutoConfig {

    public CustomMetricsAutoConfig() {
        System.out.println("CustomMetricsAutoConfig initialized (After FrameworkAutoConfig)");
    }
}

In this example, CustomLoggingAutoConfig is configured to load before FrameworkAutoConfig, while CustomMetricsAutoConfig is set to load afterwards, and FrameworkAutoConfig itself is assigned a higher priority through the use of @AutoConfigureOrder(1).

5. Conclusion

In this article, we explored how Spring Boot determines configuration order, how the framework initializes beans, and the different ways we can influence this sequence. We looked at the default behaviour, how annotations such as @Order and @DependsOn help control initialization, and how auto configuration rules guide startup.

6. Download the Source Code

This article provided a detailed look at Spring Boot configuration order.

Download
You can download the full source code of this example here: spring boot configuration order

Omozegie Aziegbe

Omos Aziegbe is a technical writer and web/application developer with a BSc in Computer Science and Software Engineering from the University of Bedfordshire. Specializing in Java enterprise applications with the Jakarta EE framework, Omos also works with HTML5, CSS, and JavaScript for web development. As a freelance web developer, Omos combines technical expertise with research and writing on topics such as software engineering, programming, web application development, computer science, and technology.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Oldest
Newest Most Voted
Back to top button