Hook: This is the one line that turns a plain Java class into a live Spring Boot app, which is why interviewers love it.
Question: What is SpringApplication.run()?
Answer: SpringApplication.run() is the main startup method in Spring Boot. It creates the Spring application context, applies auto-configuration, scans and wires beans, and starts the embedded web server if the app is a web app. It also processes command-line arguments and returns the running context so you can access beans after startup.
Interview-Ready Answer: I use SpringApplication.run() as the bootstrap call that launches a Spring Boot app. It builds and refreshes the application context, loads beans, applies auto-configuration, and starts the embedded server when needed. It also returns the live context, so after startup I can still inspect or use beans, which is a nice detail interviewers often like to hear.
SpringApplication.run() is the convenience entry point for a Spring Boot app. Think of it as the method that takes your application class and launch arguments, then performs the whole bootstrapping sequence for you. The key idea is that it does startup orchestration for the app, not business logic.
SpringApplication instance from your primary source class, usually the class marked with @SpringBootApplication.application.properties or application.yml. This is where profile-specific config like application-dev.yml can take effect.@Configuration classes, and auto-configuration. Auto-configuration is Boot’s smart default setup that turns on useful beans based on what it finds on the classpath and in properties.CommandLineRunner and ApplicationRunner beans, then publishes ready events. Finally, run() returns the live context object.Use SpringApplication.run() in almost every standard Spring Boot application. It is the normal entry point for REST APIs, MVC apps, batch-like command apps, and many internal services. You usually do not use it inside unit tests, because tests typically load a smaller slice of the app or a test context instead.
| Option | Best for | Key idea |
|---|---|---|
SpringApplication.run() | Most apps | Fastest, standard bootstrap |
SpringApplicationBuilder | Custom startup | Fluent setup, parent-child contexts, more control |
| Manual context creation | Low-level needs | You wire more yourself; Boot magic is reduced |
The table matters because interviewers often want to know whether you understand the difference between the simple default path and the custom path. For most production code, the static run() call is enough. Reach for the builder only when you need special context hierarchy, custom listeners, or a very tailored boot sequence.
Startup time is not constant; it grows with the number of beans, the amount of classpath scanning, and how much auto-configuration the app triggers. A small Boot service might start in under 2 seconds on a warm machine, while a larger service can take 5 to 15 seconds cold depending on dependencies and hardware. Memory usage at startup is often in the 100 to 300 MB range for a typical service, but this varies a lot.
Important edge cases:
run() throws an exception and the process exits with a non-zero code.Memory hook: think of SpringApplication.run() as the stage manager for a show: it sets the lights, opens the curtains, and hands you the live stage after everything is ready.
Imagine an e-commerce checkout service. On deploy, SpringApplication.run() reads the payment gateway settings, creates the checkout beans, starts embedded Tomcat, and then the service becomes ready for traffic. If a secret is missing or a database URL is wrong, the app never becomes healthy, which is exactly what you want in production.
What goes wrong: a team sets an invalid property for the database connection, so startup fails during bean creation. In Kubernetes, the pod keeps restarting, logs show Application run failed, readiness probes never pass, and customers cannot place orders. From the outside it looks like a complete outage, but the root cause is usually one boot-time configuration mistake.
That is why understanding run() matters: it is not just a method call, it is the point where config mistakes become visible before the app starts serving real users.
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// SpringApplication.run() does the bootstrapping work:
// it prepares the environment, creates the context, starts the embedded server,
// and returns the live application context.
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
// This shows the practical value of the return type: you can inspect the running app.
System.out.println("Bean count after startup: " + context.getBeanDefinitionCount());
}
@Bean
CommandLineRunner startupChecks(ApplicationArguments arguments) {
return args -> {
// Edge case / failure path:
// If a bad startup flag is passed, fail fast instead of letting the app run in a broken state.
if (arguments.containsOption("fail-startup")) {
throw new IllegalStateException("Startup aborted because --fail-startup was provided.");
}
System.out.println("Non-option args: " + arguments.getNonOptionArgs());
System.out.println("Option names: " + arguments.getOptionNames());
};
}
@Bean
GreetingService greetingService() {
return new GreetingService();
}
@RestController
static class HelloController {
private final GreetingService greetingService;
HelloController(GreetingService greetingService) {
this.greetingService = greetingService;
}
@GetMapping("/hello")
ResponseEntity<String> hello(@RequestParam(defaultValue = "world") String name) {
// A safe default keeps the endpoint easy to call after the app has started.
return ResponseEntity.ok(greetingService.greet(name));
}
@GetMapping("/divide")
ResponseEntity<String> divide(@RequestParam int x, @RequestParam int y) {
// Small error-handling example: a bad request should not become a server crash.
if (y == 0) {
return ResponseEntity.badRequest().body("y must not be 0");
}
return ResponseEntity.ok(String.valueOf(x / y));
}
}
static class GreetingService {
String greet(String name) {
return "Hello, " + name + "!";
}
}
}Follow-up & Tricky Questions:
SpringApplication.run() return? It returns a running ApplicationContext object, usually a ConfigurableApplicationContext, so you can access beans or close the app if needed.run() block? Yes, it blocks until startup is complete. For a web app, the main thread finishes startup and then the embedded server handles requests on its own threads.ApplicationRunner and CommandLineRunner, and some args can override config properties.SpringApplication settings, listeners, profiles, or SpringApplicationBuilder when you need more control than the one-line default.Tricky / gotcha questions:
SpringApplication.run() the same as main()? No. main() is just the Java entry point; run() is the Spring Boot bootstrap engine that actually starts the app.run() automatically find every class on the classpath? No. It uses component scanning and auto-configuration rules, so package structure and annotations still matter a lot.Common Mistakes:
run() is startup plumbing, not a place for application rules or request handling.Memory Hook: main() turns the key, and SpringApplication.run() drives the car onto the road.
Cheat Sheet:
Practice Tasks:
--fail-startup and observe how Spring Boot stops before serving traffic.