Skip to main content

SpringApplication.run() : What Happens Inside ?

Spring Boot Internals: What Happens Inside SpringApplication.run()?

If you are a backend developer with 3+ years of experience, interviewers expect you to know exactly how Spring Boot operates under the hood. When asked, "How does a Spring Boot application start?", most candidates answer: "SpringApplication.run() starts the application."

That answer guarantees a rejection. Interviewers want to know the exact internal workflow: how the IOC container boots up, how auto-configuration triggers, and how Tomcat embeds itself. Let us dive deep into the internal mechanics of Spring Boot's startup phase.


The Entry Point

@SpringBootApplication
public class EmployeeApplication {

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

When the JVM executes the main() method, it calls SpringApplication.run(). This single line of code triggers a massive 14-step internal initialization chain.

The 14-Step Internal Workflow

JVM Executes main()
Create SpringApplication Object
Prepare Environment
Create ApplicationContext (IOC)
Component Scan & Bean Definitions
Bean Creation & Dependency Injection
Auto Configuration
context.refresh()
Start Embedded Tomcat
Application Ready

Step 1 & 2: Object Creation & App Type

Spring Boot first instantiates the SpringApplication object itself. It then inspects your classpath dependencies to determine the application type. If it detects spring-boot-starter-web, it classifies the app as a Servlet-based application and selects the AnnotationConfigServletWebServerApplicationContext.

Step 3 & 4: Environment & ApplicationContext

Spring creates the ConfigurableEnvironment object. This object reads your application.properties, environment variables, and JVM arguments, storing them securely so annotations like @Value can access them later. Next, Spring creates the actual ApplicationContext—the massive IOC container that will eventually hold all your Beans.

Step 5 & 6: Component Scan & Bean Definitions

Spring detects the @SpringBootApplication annotation (which secretly contains @ComponentScan). It recursively scans your packages for @Controller, @Service, and @Repository classes.

Crucial detail: Spring does not create the objects immediately. First, it generates a Bean Definition—a structural blueprint containing the bean's name, type, scope, and required dependencies.

Step 7 & 8: Bean Instantiation & Dependency Injection

Using the blueprints, Spring instantiates the actual singleton objects. If an EmployeeService requires an EmployeeRepository, Spring searches the IOC container, locates the repository, and automatically injects it into the service's constructor.

Step 9: Auto Configuration

The framework reads the AutoConfiguration.imports file hidden inside its internal libraries. It evaluates hundreds of conditional classes using annotations like @ConditionalOnClass. If you included the MySQL driver, Spring automatically builds a DataSource bean. If the driver is missing, it simply skips it.

Step 10: Context Refresh (The Most Important Phase)

Spring executes context.refresh(). This command acts as the absolute heart of the Spring Framework. It finalizes Bean creation, executes Bean Post Processors, generates AOP proxies, and officially wires the entire IOC container together. Without this command, the application cannot start.

Step 11 & 12: Embedded Tomcat & DispatcherServlet

Spring Boot creates a TomcatServletWebServerFactory, which boots up the embedded Tomcat server internally on port 8080. It then registers the DispatcherServlet directly into Tomcat to intercept incoming HTTP traffic. Finally, it fires the ApplicationReadyEvent.

Interview Answer: What happens when the app starts?

"When SpringApplication.run() executes, Spring Boot creates the SpringApplication object, prepares the environment properties, and initializes the ApplicationContext (IOC container). It performs component scanning to register Bean Definitions, instantiates those singleton beans, and injects their dependencies. Next, it applies Auto-Configuration based on classpath conditions. It then executes context.refresh() to finalize the IOC container, boots up the embedded Tomcat server, registers the DispatcherServlet, and marks the application as ready."


The @Configuration Annotation Deep Dive

Many developers assume @Configuration only serves to hold @Bean methods. However, it possesses a critical secondary behavior regarding memory management that interviewers frequently test.

Why Do We Need @Bean Methods?

Normally, you annotate your classes with @Service or @Component so Spring can discover them. But what if you need to use a class from a third-party library, an external SDK, or legacy code? You cannot open their source code to add a @Service annotation.

To solve this, you use @Configuration and @Bean to manually instantiate the object and hand it directly to the IOC container.

@Configuration
public class AppConfig {

    @Bean
    public ExternalLibraryService externalService() {
        return new ExternalLibraryService();
    }
}

The Trap: @Configuration vs @Component

Because @Configuration is meta-annotated with @Component, Spring creates a bean for the AppConfig class itself. You could theoretically swap the annotation to @Component and your application would still compile. However, doing so destroys Spring's singleton guarantees.

@Configuration
public class AppConfig {

    @Bean
    public Employee employee() {
        return new Employee();
    }

    @Bean
    public Department department() {
        // Calling the employee() method directly
        return new Department(employee());
    }
}

Notice that the department() method directly invokes the employee() method. If this was a standard Java class, new Employee() would execute twice, creating two completely different objects in memory.

The CGLIB Proxy Magic

When you use @Configuration, Spring secretly wraps your class in a CGLIB Proxy (e.g., AppConfig$$EnhancerBySpringCGLIB). This proxy intercepts every single call to your @Bean methods.

When department() calls employee(), the CGLIB proxy catches the method call, checks the IOC container, and says: "Wait, an Employee bean already exists in memory! Do not run this method again; just return the existing singleton object."

If you mistakenly use @Component instead, Spring does not generate this proxy. The method will execute twice, generating duplicate objects and instantly breaking your singleton architecture.

Interview Answer: The Purpose of @Configuration

"@Configuration marks a class as a Spring configuration file used to declare manual beans via @Bean methods. Crucially, Spring wraps @Configuration classes in a CGLIB proxy. This proxy intercepts internal method calls to ensure that if one @Bean method calls another, it returns the existing managed singleton from the IOC container rather than creating a duplicate object. Standard @Component classes do not generate this proxy and will break singleton scopes if methods invoke each other."

Comments

Popular posts from this blog

How I Got Selected in MNC

Virtusa Sometimes success does not come from having the best coding skills or the perfect roadmap. Sometimes it comes from simply refusing to quit. This is the honest story of how I transitioned from a confused, rejected fresher to getting selected as an Associate Engineer at Virtusa. The Beginning: Confused About My Future After completing my graduation, I stared blankly at my career options. Like many freshers, I lacked a clear direction. Should I join a Java course? Should I prepare on my own? Should I just wait for campus placement opportunities? One day, I called my friend Chetan. He suggested I join Naresh i Technologies and start learning Java seriously. Still unsure of my path, I told him I needed time to think about it. A couple of days later, my phone buzzed with a WhatsApp message offering a job opportunity. They asked me to come for the next round of the recruitment process. Excitement completely took over. I packed my bags, traveled to th...

Spring Boot Introduction

Spring Boot Introduction: Architecture, Dependencies, and Embedded Servers Modern enterprise applications demand rapid development, frictionless deployment, and absolute minimal configuration. Before Spring Boot arrived, developers utilizing the Spring Framework wasted immense amounts of time configuring XML files, managing clashing dependencies, setting up clunky application servers, and stitching various Spring modules together manually. To eliminate these bottlenecks, Pivotal introduced Spring Boot . Built entirely on top of the traditional Spring Framework, Spring Boot is an "opinionated" framework. It aggressively simplifies application development by injecting auto-configuration, packaging starter dependencies, and embedding web servers directly into your application. This allows backend developers to focus entirely on building business logic rather than wrestling with infrastructure setup. What is Spring Boot? Spring Boot is a powerful extens...

Data Types in C

C Programming: Understanding Data Types Think of your kitchen. You store a large bag of flour in a big bin, a pinch of saffron in a tiny jar, and milk in a liquid measuring jug. You do not put liquids into paper bags, and you do not use a massive bucket for a single teaspoon of sugar. C programming works the exact same way. When you create a variable, you must tell the computer exactly what kind of "container" to build in its memory. We call these containers Data Types . They dictate what kind of data the container holds, how much space it takes up, and what operations you can perform on it. 1. Primitive Data Types C offers several built-in, "primitive" data types. Think of these as the fundamental storage containers. int (Integer): You use this to store whole numbers without decimals. Real-life example: Counting the number of people in a room or tracking a player's score in a video game. char (Character): You use this ...