Java Spring Boot

Understanding the SpringApplication.run Method in Spring Boot

In This Article

We explore the process triggered by the SpringApplication.run() method in Spring Boot. You'll learn how the SpringApplication instance is initialized, how the environment and application context are prepared, and the key steps leading to the application's final startup. By understanding these mechanics, you'll gain a deeper insight into Spring Boot's efficient and seamless application launch process.

Spring Boot is well-known for its ability to simplify the process of setting up and running a Spring-based application. One of the central features that makes this possible is the SpringApplication.run() method. When you run a Spring Boot application, you often invoke this method as the entry point. However, have you ever wondered what actually happens behind the scenes?

In this blog, we’ll explore what occurs when SpringApplication.run() is executed, diving into the process that eventually leads to the execution of the constructor you shared earlier. By understanding this, you’ll gain deeper insights into how Spring Boot starts up, configures itself, and prepares your application to run.

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 constructor you shared is then called:

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: All beans defined in the application are created and dependencies are injected.
  • 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.

Whether you’re building a simple REST API or a complex microservices architecture, knowing how Spring Boot initializes your application can help you better manage your application’s lifecycle, troubleshoot issues, and optimize performance.