SpringApplication

Complete Beginner-Friendly Chapter — How Spring Boot Starts, Configures, and Runs Your Application
Big idea: 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.

1. What is SpringApplication?

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.

main()SpringApplicationApplicationContextBeansRunnersReady
Interview point: Yes — this is important for Spring Boot interviews. Understand what SpringApplication.run() does at a high level.

2. What Happens When You Call run()?

  1. Spring Boot starts the application.
  2. It prepares the environment.
  3. It creates and prepares the appropriate ApplicationContext.
  4. It loads bean definitions and refreshes the context.
  5. It determines application availability.
  6. It runs ApplicationRunner and CommandLineRunner components.
  7. It marks the application ready to accept traffic.
This is a simplified learning model. The exact lifecycle is represented by Spring Boot application events.

3. Startup Failure

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

4. Lazy Initialization

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);
NormalLazy
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.
Lazy initialization is not enabled by default because it can delay failure discovery and requires care with JVM memory.

You can opt a particular bean out with @Lazy(false).

5. Customizing the Banner

Spring Boot can print a startup banner. Customize it with banner.txt on the classpath or spring.banner.location.

src/main/resources/banner.txt
VariableMeaning
${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.

6. Customizing SpringApplication

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.

7. SpringApplicationBuilder

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);
Parent ContextChild Context

Web components should be contained in the child context, and parent and child use the same Environment.

8. Application Availability

StateMeaningInfrastructure response
LivenessCan the application continue or recover?Restart if it cannot recover.
ReadinessIs the application ready to receive traffic?Do not route traffic while not ready.
Important: Liveness should generally not depend on external systems such as a database or external API, otherwise an external outage can trigger unnecessary restarts.
Easy memory: Liveness = “Should I restart you?”
Readiness = “Should I send traffic to you?”

9. ApplicationAvailability

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
            }
        }
    }
}

10. Application Events and Listeners

OrderEventSimple meaning
1ApplicationStartingEventRun begins.
2ApplicationEnvironmentPreparedEventEnvironment is known.
3ApplicationContextInitializedEventContext is prepared.
4ApplicationPreparedEventBean definitions loaded before refresh.
5ApplicationStartedEventContext refreshed, before runners.
6AvailabilityChangeEventLiveness becomes CORRECT.
7ApplicationReadyEventRunners completed.
8AvailabilityChangeEventReadiness becomes ACCEPTING_TRAFFIC.
9ApplicationFailedEventStartup failed.

Other events can appear in the lifecycle, including WebServerInitializedEvent and ContextRefreshedEvent.

Application event listeners run in the same thread by default. Avoid putting lengthy work directly inside them; runners are often more appropriate for startup tasks.

11. Web Environment Detection

Dependencies presentContext selected
Spring MVCAnnotationConfigServletWebServerApplicationContext
No MVC + WebFluxAnnotationConfigReactiveWebServerApplicationContext
NeitherAnnotationConfigApplicationContext

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.

12. Application Arguments

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.

13. ApplicationRunner vs CommandLineRunner

FeatureCommandLineRunnerApplicationRunner
Methodrun(String... args)run(ApplicationArguments args)
ArgumentsRaw stringsParsed application arguments
Best forSimple startup tasksStructured argument handling

CommandLineRunner

@Component
public class MyCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) {
        System.out.println("Application started!");
    }
}

ApplicationRunner

@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.

Interview point: CommandLineRunner receives raw String... arguments; ApplicationRunner receives the richer ApplicationArguments abstraction.

14. Application Exit

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.

15. Admin Features

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.

16. Application Startup Tracking

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.

17. Virtual Threads

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
When virtual threads are enabled, properties configuring traditional thread pools no longer have their usual effect.

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

18. Complete Startup Mental Model

main()SpringApplication.run()EnvironmentApplicationContextBeansApplicationStartedEventRunnersApplicationReadyEventReadiness

19. Common Beginner Mistakes

MistakeCorrect 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.

20. Interview Questions

  1. What is SpringApplication?
  2. What does SpringApplication.run() do?
  3. What is the role of ApplicationContext?
  4. How does Spring Boot choose the web application type?
  5. What is lazy initialization?
  6. Why is lazy initialization not enabled by default?
  7. How do you disable the Spring Boot banner?
  8. What is SpringApplicationBuilder?
  9. What is the difference between liveness and readiness?
  10. Why should liveness generally not depend on external systems?
  11. What is ApplicationAvailability?
  12. Name the main Spring Boot startup events in order.
  13. Difference between CommandLineRunner and ApplicationRunner?
  14. How do you control runner ordering?
  15. How does Spring Boot handle graceful shutdown?
  16. What is ExitCodeGenerator?
  17. What is ApplicationStartup used for?
  18. What should you consider when enabling virtual threads?

21. Practice Exercises

Exercise 1: Create a basic Spring Boot application using SpringApplication.run().
Exercise 2: Disable the banner using a property and Java code.
Exercise 3: Enable lazy initialization and explain one benefit and one drawback.
Exercise 4: Create one CommandLineRunner and one ApplicationRunner.
Exercise 5: Pass --debug logfile.txt and read the option and non-option argument.
Exercise 6: Create a listener for ApplicationReadyEvent.
Exercise 7: Explain why a database outage should generally not make the liveness state fail.

22. Quick Cheat Sheet

NeedUse
Start applicationSpringApplication.run(...)
Customize startupCreate a SpringApplication instance
Context hierarchySpringApplicationBuilder
Lazy initializationspring.main.lazy-initialization=true
Disable bannerspring.main.banner-mode=off
Startup taskCommandLineRunner / ApplicationRunner
Read CLI argumentsApplicationArguments
AvailabilityApplicationAvailability
Lifecycle listenersApplicationListener / event listeners
Custom exit statusExitCodeGenerator
Startup profilingApplicationStartup
Virtual threadsspring.threads.virtual.enabled=true
Keep JVM alive with virtual threadsspring.main.keep-alive=true

23. Final Takeaway

Remember:

SpringApplication = Spring Boot's startup manager.
run() = bootstrap and start the application.
ApplicationContext = Spring's bean container.
ApplicationRunner / CommandLineRunner = startup code before readiness.
Liveness = can the application recover/work internally?
Readiness = should the platform send traffic?
Application events = lifecycle signals during startup.
ApplicationStartup = understand/profile startup work.
Virtual threads = modern concurrency with JVM-lifecycle considerations.