How a Spring Boot Application Works (Under the Hood)
1) Launch & bootstrap
-
main()callsSpringApplication.run(App.class, args). -
SpringApplication decides the app type (Servlet/WebFlux/none), sets up Bootstrap logging, loads
ApplicationContexttype, banner, listeners, and default converters.
2) Create the ApplicationContext
- It creates an IoC container (
AnnotationConfigApplicationContextfor non-web,ServletWebServerApplicationContextfor MVC, orReactiveWebServerApplicationContextfor WebFlux). -
Environment (profiles, properties) is prepared: command-line args,
application.yml/properties, OS env vars, system props, profile-specific files (application-dev.yml), and anyPropertySourceyou add.
3) Auto-configuration & component scanning
-
@SpringBootApplication=@Configuration+@EnableAutoConfiguration+@ComponentScan. -
Component scan finds your
@Component,@Service,@Repository,@Controller/@RestController,@Configurationclasses. -
Auto-configuration imports a curated set of
@Configurationclasses based on the classpath & Environment (e.g., ifspring-boot-starter-webis present, it configures Spring MVC, Jackson, an embedded server, etc.).- Runs via conditions:
@ConditionalOnClass,@ConditionalOnMissingBean,@ConditionalOnProperty, etc. - Since Spring Boot 3, auto-config classes are listed in
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports(replacing oldspring.factoriesapproach).
- Runs via conditions:
4) Bean creation & lifecycle
- The container registers bean definitions (from your app + auto-config) and then instantiates beans in dependency order.
- Lifecycle hooks apply: constructor injection â
@PostConstruct(orInitializingBean.afterPropertiesSet) âBeanPostProcessors(AOP proxies created here) â ready. - If a bean fails its condition, Boot backs off so your custom bean wins (
@ConditionalOnMissingBean).
5) Externalized configuration binding
- Boot binds properties to strongly typed configs using
@ConfigurationProperties(via the Binder API) and also to@Valuefields. -
Relaxed binding:
my.service-timeout,my.serviceTimeout,MY_SERVICE_TIMEOUTall map tomy.service-timeout.
Short example:
@ConfigurationProperties(prefix="app.greeting")
public record GreetingProps(String message, int repeat) {}
6) Web stack setup (Servlet or Reactive)
Servlet/MVC path
13. Boot starts an embedded server (Tomcat/Jetty/Undertow) via ServletWebServerFactory.
14. Registers DispatcherServlet, Filters, Servlets, and MVC infrastructure (HandlerMappings, HandlerAdapters, MessageConverters, ExceptionResolvers).
15. An HTTP request flows:
- Server â Filter chain â
DispatcherServlet - Choose handler (controller) via HandlerMapping
- Invoke controller method (argument resolvers bind path/query/body)
- Return value written via HttpMessageConverters (e.g., JSON via Jackson)
- Exception handling via
@ControllerAdvice/ resolvers - Response â Filters â client
Reactive/WebFlux path
16. Starts Netty (via Reactor Netty), sets up DispatcherHandler, HandlerMappings/Adapters/ResultHandlers, and encoders/decoders for reactive types (Mono/Flux).
7) Actuator, metrics, health
-
If
spring-boot-starter-actuatoris present, Boot auto-configures /actuator endpoints (health, metrics, info), Micrometer registry, and health contributors (DB, disk, etc.). Secure & expose endpoints based on properties.
8) Application events & runners
- Boot publishes lifecycle events (ApplicationStarting â EnvironmentPrepared â Prepared â Started â Ready).
- Your
CommandLineRunner/ApplicationRunnerbeans run after context is ready (great for seeding data, warmups).
@SpringBootApplication
@EnableConfigurationProperties(GreetingProps.class)
public class App {
public static void main(String[] args) { SpringApplication.run(App.class, args); }
@Bean CommandLineRunner runner(GreetingProps p) {
return args -> { for (int i=0; i<p.repeat(); i++) System.out.println(p.message()); };
}
}
9) Packaging & execution model
- Boot builds a fat/uber JAR with a custom Spring Boot Loader; you can
java -jar app.jar. It sets up a layered classloader so dependencies and app classes are isolated (helps with Docker layering too).
10) Profiles & environment-specific beans
- Use
@Profile("dev")/spring.profiles.active=prodto switch beans and properties per environment. Conditions can also check Cloud platforms, presence of libs, or flags.
11) Security (if added)
-
Adding
spring-boot-starter-securityauto-configures a security filter chain with sensible defaults (CSRF, basic login) and you customize viaSecurityFilterChainbeans.
12) AOT & native images (optional)
- With Spring AOT & GraalVM Native, Boot can generate ahead-of-time hints (reflection, proxies) to build native binaries for super-fast startup & low memory.
TL;DR sequence
main() â SpringApplication prepares env â create ApplicationContext â component scan + conditional auto-config â bind externalized config â create/proxy beans â start embedded server (or Netty) â register dispatch layer â run runners â Ready.