What Happens Internally When You Start A Spring Boot Application(Part1)

ApplicationContext creation/registration , AutoConfiguration .. .

Hamza Nassour
Javarevisited

--

In this article, we will explore what happens when we click the ‘run’ button in our IDE to run our Spring Boot application. There are many interesting things to discover, so get ready to dive into the internal workings of Spring Boot.

As we all know, the main method of the project serves as the entry point, but what actually happens when this method is executed ?

This is the main method we’ll be discussing:

@SpringBootApplication
public class SpringBootIntroApplication {

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

}

Despite the simplicity of Spring Boot’s startup process, there is a lot going on behind the scenes. In just one line of code, Spring Boot is able to perform a wide range of tasks. Let’s take a deeper dive to understand exactly what is happening under the hood

run() method in the SpringApplication class .

public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);

try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), timeTakenToStartup);
}

listeners.started(context, timeTakenToStartup);
this.callRunners(context, applicationArguments);
} catch (Throwable var12) {
this.handleRunFailure(context, var12, listeners);
throw new IllegalStateException(var12);
}

try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
return context;
} catch (Throwable var11) {
this.handleRunFailure(context, var11, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var11);
}
}

Note: The following code snippet is an internal implementation of the run method in a Spring Boot project. We will use it as a reference in this article and is not expected to understand it 100 % .

When you invoke the run method of SpringApplication, it creates a WebApplicationContext for your web application. If you look at the implementation of the run method, you will see that its return type is ConfigurableApplicationContext. This interface is implemented directly or indirectly by all the Application Contexts .

The type of WebApplicationContext that is created depends on the type of your web application. For example, if your application is a Servlet-based web application, Spring Boot creates a AnnotationConfigServletWebServerApplicationContext. On the other hand, if your application is a Reactive web application, Spring Boot creates a AnnotationConfigReactiveWebServerApplicationContext. This way, Spring Boot determines the type of your web application and creates the appropriate WebApplicationContext accordingly.

I understand that you’re curious about how Spring Boot determines the type of web application. It’s a great question, and I’d be happy to explain it to you.

Let me explain this to you, Spring Boot internally classifies web applications into two categories: Reactive and Servlet applications using the WebApplicationType enumeration.

in the constructor of the SpringApplication class you will find this line :

this.webApplicationType = WebApplicationType.deduceFromClasspath();

spring-boot uses the deduceFromClasspath() method to determine the type of web application based on the presence of certain dependencies on the classpath. If it finds the spring-boot-starter-web dependency, it will assume that the application is a Servlet-based web application and set the webApplicationType attribute to SERVLET. Similarly, if it finds the spring-boot-starter-reactive dependency, it will assume that the application is a reactive web application and set the webApplicationType to REACTIVE. If none of these dependencies are found, they webApplicationType will be set to NONE.

based on this application type Spring Boot will create the appropriate application context but how?

context = this.createApplicationContext();
protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}

The createApplicationContext() method in SpringApplication creates the appropriate application context based on the detected webApplicationType. It delegates the task of creating the context to an instance of ApplicationContextFactory, which is passed the detected webApplicationType as a parameter.

The ApplicationContextFactory interface defines a single method create(WebApplicationType), which returns a new ConfigurableApplicationContext based on the given WebApplicationType.

to check if the run method return the appropriate webApplicationContext :

public static void main(String[] args) {
ConfigurableApplicationContext run = SpringApplication.run(SpringBootIntroApplication.class, args);
System.out.println(run instanceof AnnotationConfigServletWebServerApplicationContext );

}

what’s happened after the context get created ?

The this.refreshContext(context) method in the run() method of SpringApplication triggers a refresh of the application context. This means that the application context will be initialized and configured with all the necessary beans and components required to run the application.

During the refresh process, Spring will scan the application’s classpath for all components that have been annotated with @Component or other annotations, and will create and configure instances of those components as necessary. It will also load and configure any other beans that are defined in the application context, such as those defined in XML configuration files or through Java configuration classes.

Once the application context has been fully refreshed and initialized, the application can start handling requests or performing other tasks.

it’s important to note that the run the method does much more than that, we focus only on how the run() method creates the WebApplicationType.

For an in-depth exploration of Spring MVC components, dive into my latest article on javalaunchpad.com titled A Closer Look at Spring MVC Architecture. where I explained the inner workings of Spring MVC components.

Thanks for reading!

--

--