Spring Boot Startup Process Overview and Source Code Analysis

This article walks through the Spring Boot startup sequence, detailing the roles of spring.factories, SpringApplication initialization, environment setup, ApplicationContext creation, and context refresh, while providing key code excerpts to illustrate each step.

Architecture Digest
Architecture Digest
Architecture Digest
Spring Boot Startup Process Overview and Source Code Analysis

The article presents a step‑by‑step examination of Spring Boot's launch process, beginning with an overview of the overall flow and the purpose of the spring.factories file located under classpath:/META-INF/.

It explains how spring.factories is a properties file that maps interface names to implementation class lists, and how SpringFactoriesLoader loads these configurations for ApplicationContextInitializer and ApplicationListener implementations.

Next, the article shows the minimal main class used to start a Spring Boot application:

@SpringBootApplication
@Slf4j
public class SpringEnvApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringEnvApplication.class, args);
    }
}

The constructor of SpringApplication performs several initializations, such as assigning basic variables, checking the ApplicationContext type, loading initializers and listeners, and deducing the main application class.

It then details the WebApplicationType.deduceFromClasspath method, which determines whether the application is a servlet, reactive, or non‑web program based on classpath presence, and lists the constants used for this detection.

The loading of ApplicationContextInitializer and ApplicationListener is described, with examples of entries from spring.factories for each.

During the environment initialization phase, the article outlines parsing command‑line arguments, creating the appropriate ConfigurableEnvironment (e.g., StandardServletEnvironment), configuring property sources, profiles, and binding SpringApplication properties from the environment.

private ConfigurableEnvironment getOrCreateEnvironment() {
    if (this.environment != null) {
        return this.environment;
    }
    switch (this.webApplicationType) {
    case SERVLET:
        return new StandardServletEnvironment();
    case REACTIVE:
        return new StandardReactiveWebEnvironment();
    default:
        return new StandardEnvironment();
    }
}

After the environment is prepared, the article moves to ApplicationContext creation, showing how the concrete context class is selected based on WebApplicationType and instantiated via BeanUtils.instantiateClass:

protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.applicationContextClass;
    if (contextClass == null) {
        try {
            switch (this.webApplicationType) {
            case SERVLET:
                contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                break;
            case REACTIVE:
                contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                break;
            default:
                contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        } catch (ClassNotFoundException ex) {
            throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
        }
    }
    return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

The preparation of the context includes setting the environment, applying initializers, registering singletons (such as springApplicationArguments and the banner), and loading configuration classes annotated with @Configuration.

private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
        SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
    context.setEnvironment(environment);
    postProcessApplicationContext(context);
    applyInitializers(context);
    listeners.contextPrepared(context);
    // register singletons, bean factory settings, etc.
    Set<Object> sources = getAllSources();
    Assert.notEmpty(sources, "Sources must not be empty");
    load(context, sources.toArray(new Object[0]));
    listeners.contextLoaded(context);
}

Refreshing the ApplicationContext is likened to starting the engine of a car, with steps such as preparing for refresh, initializing the BeanFactory, invoking BeanFactoryPostProcessors, registering BeanPostProcessors, initializing message sources and event broadcasting, and finally registering ApplicationListeners.

After the context is refreshed, Spring Boot runs any ApplicationRunner or CommandLineRunner beans, allowing custom startup logic (e.g., launching Dubbo or gRPC services):

private void callRunners(ApplicationContext context, ApplicationArguments args) {
    List<Object> runners = new ArrayList<>();
    runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
    runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
    AnnotationAwareOrderComparator.sort(runners);
    for (Object runner : new LinkedHashSet<>(runners)) {
        if (runner instanceof ApplicationRunner) {
            callRunner((ApplicationRunner) runner, args);
        }
        if (runner instanceof CommandLineRunner) {
            callRunner((CommandLineRunner) runner, args);
        }
    }
}

The article concludes that Spring Boot’s startup code is relatively easy to follow, mainly providing a convenient entry point for ApplicationContext initialization and emphasizing the importance of automatic configuration.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaSpringBootstartupSpringFramework
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.