SpringApplication is the main Spring Boot bootstrap class. It helps create and configure the ApplicationContext, start the application, process startup events and runners, and manage shutdown.In a normal Java program, the JVM starts from the main() method. In Spring Boot, that method commonly delegates startup work to SpringApplication.run().
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Think of SpringApplication as the starter/manager of your Spring Boot application.
SpringApplication.run() does at a high level.ApplicationContext.ApplicationRunner and CommandLineRunner components.When startup fails, Spring Boot can use FailureAnalyzer implementations to provide a useful description and suggested action.
*************************** APPLICATION FAILED TO START *************************** Description: Embedded servlet container failed to start. Port 8080 was already in use. Action: Identify and stop the process listening on port 8080 or configure the application to use another port.
If no failure analyzer handles the problem, enable the conditions report with:
java -jar myproject-0.0.1-SNAPSHOT.jar --debug
Lazy initialization means beans are created when they are needed instead of all being created during startup.
spring.main.lazy-initialization=true
SpringApplication application = new SpringApplication(MyApplication.class); application.setLazyInitialization(true); application.run(args);
| Normal | Lazy |
|---|---|
| More beans created at startup. | Beans created as needed. |
| Potentially slower startup. | Can reduce startup time. |
| Configuration problems can appear early. | Some failures can be delayed until a bean is used. |
You can opt a particular bean out with @Lazy(false).
Spring Boot can print a startup banner. Customize it with banner.txt on the classpath or spring.banner.location.
src/main/resources/banner.txt
| Variable | Meaning |
|---|---|
${application.version} | Application version from the manifest. |
${application.formatted-version} | Formatted application version. |
${spring-boot.version} | Spring Boot version. |
${spring-boot.formatted-version} | Formatted Boot version. |
${application.title} | Application title. |
Banner output can be controlled with:
spring.main.banner-mode=off
Supported modes are console, log, and off.
SpringApplication application =
new SpringApplication(MyApplication.class);
application.setBannerMode(Banner.Mode.OFF);
application.setLazyInitialization(true);
application.run(args);
The constructor arguments are configuration sources for Spring beans. Usually these are configuration classes, but they can also be component classes.
Use SpringApplicationBuilder when you want a fluent API or an ApplicationContext hierarchy.
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
Web components should be contained in the child context, and parent and child use the same Environment.
| State | Meaning | Infrastructure response |
|---|---|---|
| Liveness | Can the application continue or recover? | Restart if it cannot recover. |
| Readiness | Is the application ready to receive traffic? | Do not route traffic while not ready. |
Application components can inject ApplicationAvailability to retrieve the current availability state.
You can also listen for changes using AvailabilityChangeEvent.
@Component
public class MyReadinessStateExporter {
@EventListener
public void onStateChange(
AvailabilityChangeEvent<ReadinessState> event) {
switch (event.getState()) {
case ACCEPTING_TRAFFIC -> {
// application can receive traffic
}
case REFUSING_TRAFFIC -> {
// application should not receive traffic
}
}
}
}
| Order | Event | Simple meaning |
|---|---|---|
| 1 | ApplicationStartingEvent | Run begins. |
| 2 | ApplicationEnvironmentPreparedEvent | Environment is known. |
| 3 | ApplicationContextInitializedEvent | Context is prepared. |
| 4 | ApplicationPreparedEvent | Bean definitions loaded before refresh. |
| 5 | ApplicationStartedEvent | Context refreshed, before runners. |
| 6 | AvailabilityChangeEvent | Liveness becomes CORRECT. |
| 7 | ApplicationReadyEvent | Runners completed. |
| 8 | AvailabilityChangeEvent | Readiness becomes ACCEPTING_TRAFFIC. |
| 9 | ApplicationFailedEvent | Startup failed. |
Other events can appear in the lifecycle, including WebServerInitializedEvent and ContextRefreshedEvent.
| Dependencies present | Context selected |
|---|---|
| Spring MVC | AnnotationConfigServletWebServerApplicationContext |
| No MVC + WebFlux | AnnotationConfigReactiveWebServerApplicationContext |
| Neither | AnnotationConfigApplicationContext |
If MVC and WebFlux are both present, MVC is used by default.
SpringApplication application =
new SpringApplication(MyApplication.class);
application.setWebApplicationType(WebApplicationType.NONE);
application.run(args);
WebApplicationType.NONE is useful when you want a non-web application or need this behavior in a test.
Arguments passed to SpringApplication.run() can be accessed through ApplicationArguments.
java -jar app.jar --debug logfile.txt
@Component
public class MyBean {
public MyBean(ApplicationArguments args) {
boolean debug = args.containsOption("debug");
List<String> files = args.getNonOptionArgs();
if (debug) {
System.out.println(files);
}
}
}
For this example, files contains logfile.txt. Spring Boot also registers a CommandLinePropertySource in the Environment.
| Feature | CommandLineRunner | ApplicationRunner |
|---|---|---|
| Method | run(String... args) | run(ApplicationArguments args) |
| Arguments | Raw strings | Parsed application arguments |
| Best for | Simple startup tasks | Structured argument handling |
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) {
System.out.println("Application started!");
}
}
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) {
if (args.containsOption("debug")) {
System.out.println("Debug mode enabled");
}
}
}
If multiple runners must execute in a specific order, use Ordered or @Order.
CommandLineRunner receives raw String... arguments; ApplicationRunner receives the richer ApplicationArguments abstraction.Each SpringApplication registers a JVM shutdown hook so the ApplicationContext can close gracefully.
You can provide custom process exit codes with ExitCodeGenerator.
@Bean
public ExitCodeGenerator exitCodeGenerator() {
return () -> 42;
}
public static void main(String[] args) {
System.exit(
SpringApplication.exit(
SpringApplication.run(MyApplication.class, args)
)
);
}
Exceptions may also implement ExitCodeGenerator. With multiple generators, the first non-zero generated exit code is used; ordering can be controlled with Ordered or @Order.
spring.application.admin.enabled=true
This exposes SpringApplicationAdminMXBean through the platform MBeanServer for remote administration and service-wrapper scenarios.
The property local.server.port can be used to find the HTTP port in applicable situations.
ApplicationStartup and StartupStep can help track and understand application startup.
SpringApplication application =
new SpringApplication(MyApplication.class);
application.setApplicationStartup(
new BufferingApplicationStartup(2048));
application.run(args);
BufferingApplicationStartup buffers startup steps. FlightRecorderApplicationStartup integrates Spring startup information with Java Flight Recorder for profiling.
java -XX:StartFlightRecording:filename=recording.jfr,duration=10s -jar demo.jar
Spring Boot can also expose startup information through the startup endpoint when configured.
Virtual threads require Java 21 or later. The current documentation strongly recommends Java 24 or later for the best experience.
spring.threads.virtual.enabled=true
Virtual threads are daemon threads. This can matter when using @Scheduled tasks because scheduler threads may not keep the JVM alive.
spring.main.keep-alive=true
| Mistake | Correct understanding |
|---|---|
Thinking SpringApplication is a controller/service. | It is primarily a bootstrap/startup mechanism. |
| Putting lengthy work in event listeners. | Use runners or an appropriate asynchronous mechanism. |
| Confusing liveness and readiness. | Liveness is recoverability; readiness is traffic acceptance. |
| Assuming WebFlux always wins. | MVC is selected by default when both MVC and WebFlux are present. |
Using CommandLineRunner for structured argument handling. | Consider ApplicationRunner. |
SpringApplication?SpringApplication.run() do?ApplicationContext?SpringApplicationBuilder?ApplicationAvailability?CommandLineRunner and ApplicationRunner?ExitCodeGenerator?ApplicationStartup used for?SpringApplication.run().CommandLineRunner and one ApplicationRunner.--debug logfile.txt and read the option and non-option argument.ApplicationReadyEvent.| Need | Use |
|---|---|
| Start application | SpringApplication.run(...) |
| Customize startup | Create a SpringApplication instance |
| Context hierarchy | SpringApplicationBuilder |
| Lazy initialization | spring.main.lazy-initialization=true |
| Disable banner | spring.main.banner-mode=off |
| Startup task | CommandLineRunner / ApplicationRunner |
| Read CLI arguments | ApplicationArguments |
| Availability | ApplicationAvailability |
| Lifecycle listeners | ApplicationListener / event listeners |
| Custom exit status | ExitCodeGenerator |
| Startup profiling | ApplicationStartup |
| Virtual threads | spring.threads.virtual.enabled=true |
| Keep JVM alive with virtual threads | spring.main.keep-alive=true |
SpringApplication = Spring Boot's startup manager.run() = bootstrap and start the application.ApplicationContext = Spring's bean container.ApplicationRunner / CommandLineRunner = startup code before readiness.