Understanding the SpringApplication.run Method in Spring Boot

Understand the Spring Boot startup lifecycle and use it to locate configuration, bean-creation, context-refresh, and runner failures.

SpringApplication.run() bootstraps a Spring Boot application: it prepares the environment, creates and refreshes an application context, and invokes startup runners. This article explains that lifecycle at a high level. The internal constructor excerpts are a simplified Spring Boot 3.x implementation sketch, not a stable public API or a complete runnable application.

The following sections trace the public startup call into a simplified initialization sequence. Use that sequence to distinguish configuration loading, context creation, bean initialization, and startup-runner failures.

The Journey Begins: SpringApplication.run()

The SpringApplication.run() method is the primary way to start a Spring Boot application. Here’s a simple example of its usage:

@SpringBootApplication
public class MySpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}
Java

When you call SpringApplication.run(MySpringBootApplication.class, args);, several important steps take place to bootstrap your application.

Step 1: Creating the SpringApplication Instance

The first thing SpringApplication.run() does is create an instance of the SpringApplication class. This is done through one of its static run methods:

public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
    return new SpringApplication(primarySources).run(args);
}
Java

This line essentially calls the constructor of the SpringApplication class:

public SpringApplication(Class<?>... primarySources) {
    this(null, primarySources);
}
Java

This constructor is responsible for initializing the core components needed to start the Spring Boot application.

Step 2: Initializing the SpringApplication Instance

The resource-loader constructor performs the initialization shown in this simplified excerpt:

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers = new ArrayList<>(
            getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}
Java

Let’s break down what happens here:

  • Resource Loader: If a custom ResourceLoader is provided, it’s set up here. If not, the default one is used. This handles how resources (like configuration files) are loaded in your application.
  • Primary Sources: The primarySources are the main configuration classes for your application, typically the class annotated with @SpringBootApplication.
  • Web Application Type: Spring Boot determines if the application is a web application or a non-web application by checking the classpath. This influences the type of ApplicationContext that will be created.
  • Bootstrap Initializers: Instances of BootstrapRegistryInitializer are created. These are used during the early phase of the application’s lifecycle to customize the bootstrap process.
  • Application Context Initializers: These are configured to allow customization of the ApplicationContext before it is refreshed.
  • Application Listeners: Listeners for various application events are set up here. These can respond to events during startup, running, and shutdown.
  • Main Application Class: The main application class is deduced, which is usually the class with the main method. This is important for logging and other contextual purposes.

Step 3: Running the Application

Once the SpringApplication instance is fully initialized, the run() method of this instance is called:

public ConfigurableApplicationContext run(String... args) {
    ...
}
Java

Here’s what happens during this run method:

  • Banner Display: The Spring Boot banner is displayed in the console, unless disabled.
  • Environment Preparation: The environment is prepared, which includes loading properties from application.properties, application.yml, system properties, environment variables, and command-line arguments.
  • Application Context Creation: Based on the application type (web or non-web), a suitable ApplicationContext is created. For web applications, a WebApplicationContext is created.
  • Context Initialization: The previously set ApplicationContextInitializers are executed to customize the context before it is refreshed.
  • Application Listeners: The application listeners are called, handling various events like context start, stop, and refresh.
  • Bean Creation and Dependency Injection: Non-lazy singleton beans are normally created during context refresh and their dependencies are injected; lazy beans may be created later.
  • Embedded Server Start (for Web Applications): If the application is a web application, the embedded server (like Tomcat or Jetty) is started.
  • Runner Execution: Beans implementing CommandLineRunner or ApplicationRunner are executed to perform any task that needs to happen after the application is fully started.

Conclusion

The SpringApplication.run() method is more than just a simple call to start your Spring Boot application. It orchestrates a series of well-defined steps, from setting up the environment and creating the application context, to starting the embedded server and executing custom runners.

Understanding what happens under the hood when you call SpringApplication.run() provides valuable insights into the powerful abstractions Spring Boot offers, making it easier for developers to create robust and scalable applications with minimal configuration.

Use the lifecycle to locate startup failures: configuration loading, bean creation, context refresh, or runner execution. For choosing environment-specific beans and settings, continue with Spring Boot profiles.

Share
Prabhat Kashyap

Prabhat Kashyap

Senior Technical Architect at HCLTech · working with Leonteq Security AG

I have 10+ years of experience building distributed systems and fintech platforms. I write about practical, non-obvious engineering details that official documentation often skips.

Newsletter

Get new engineering deep dives

Scala, JVM, AI, and backend systems. I send practical articles when there is something worth reading.

Join the newsletter