Core Process Overview
In Spring Boot applications, we typically write a class containing a main method and call `SpringApplication.run`.
Example code:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The entire startup process can be summarized as: constructing SpringApplication an object -> executing run a method -> starting the embedded server -> completing application startup .
Phase 1: SpringApplication Instantiation
Execution method:new SpringApplication(primarySources)
- implement
this(null, primarySources):- Function : Calls the internal constructor.
- The most important part is
WebApplicationType.deduceFromClasspath()the method :- The purpose of this method is to infer the application type based on the classes that exist in the classpath.
- It checks the existence of classes like `<application>`
DispatcherHandler,DispatcherServlet` <script>`, and `<script>` to determine whether the application is a reactive, a standard Servlet web application, or a non-web application. The most common Spring MVC application is the `<application>` type.ServletREACTIVESERVLETNONESERVLET
- Execution
setInitializersmethod :- Function : Sets the application initializer (
ApplicationContextInitializer). - The most important part is
getSpringFactoriesInstances(ApplicationContextInitializer.class)the method :- The purpose of this method is to use Spring’s factory loading mechanism
META-INF/spring.factoriesto load and instantiateApplicationContextInitializerthe implementation classes of all configurations from the configuration file. - Common initializers include those
ConfigurationWarningsApplicationContextInitializerfor checking configuration warnings andContextIdApplicationContextInitializersetting the context ID. These initializers areApplicationContextcalled before a refresh.
- The purpose of this method is to use Spring’s factory loading mechanism
- Function : Sets the application initializer (
- Execution
setListenersmethod :- Function : Set the application listener (
ApplicationListener). - The most important part is also
getSpringFactoriesInstances(ApplicationListener.class)the method :- The purpose of this method is
spring.factoriesto load and instantiate all configurations from itApplicationListener. - These listeners are used to listen for various events published during application startup, such as `
ApplicationStartedEventclear cache` and `check file encoding`.ApplicationReadyEventClearCachesApplicationListenerFileEncodingApplicationListener
- The purpose of this method is
- Function : Set the application listener (
- Execution
deduceMainApplicationClassmethod :- Purpose : To deduce the main application class (i.e., the class in which we wrote
mainthe methods). - The principle is : traverse the current call stack and find the first
mainclass whose method name is [name missing].
- Purpose : To deduce the main application class (i.e., the class in which we wrote
At this point, SpringApplication the object has been constructed, and its initializer and listener are ready.
Phase Two: Execution run Method
Execution method:SpringApplication.run(primarySources, args)
This is the most crucial and complex method in the entire startup process.
- Execute
getRunListenersand call the methodlisteners.starting():- Function : To retrieve
SpringApplicationRunListenersand publishApplicationStartingEventevents. - Note :
SpringApplicationRunListenersThis isSpringApplicationRunListenera collection specifically designed to listen for key moments in the execution of methods. The first step is to publish events indicating that the applicationSpringApplicationis starting up .run
- Function : To retrieve
- Execution
prepareEnvironmentmethod :- Function : To prepare and apply the environment (
Environment), which is the foundation of the entire application configuration. - The most important part is :
getOrCreateEnvironment()CreateStandardEnvironmentor based on application typeStandardServletEnvironment.configureEnvironment(environment, args): Configure the environment, includingPropertySources(property sources, such as JVM system properties, operating system environment variables) andProfiles(configuration files, such as “dev”, “prod”).listeners.environmentPrepared(environment): PublishApplicationEnvironmentPreparedEventthe event. This is an extremely important extension point . The listener for this event (most notablyConfigFileApplicationListener) will load our custom configuration properties from files such asapplication.properties.application.yml
- Function : To prepare and apply the environment (
- Execution
printBannermethod :- Function : Prints the Spring Boot banner to the console.
- Execution
createApplicationContextmethod :- Function : Creates
ApplicationContext(IoC container). - Based on the deduction made in the first step
WebApplicationType, different types of contexts are created. For Servlet web applications, this will be doneAnnotationConfigServletWebServerApplicationContext.
- Function : Creates
- Execution
prepareContextmethod :- Function : To prepare the data created above
ApplicationContext. - The most important part is :
postProcessApplicationContext(context)Post-processing application context, such as setting up bean name generators and resource loaders.applyInitializers(context): Application initializerApplicationContextInitializer. Calls all methods loaded in the first stepinitialize, allowing us to customize the context before the container is refreshed.listeners.contextPrepared(context): PublishApplicationContextInitializedEventan event to notify the listener that the context is ready.load(context, sources.toArray(new Object[0]))Load the main source (i.e., our@SpringBootApplicationannotation class) into the context to prepare for subsequent component scanning and bean definition registration.listeners.contextLoaded(context): PublishApplicationPreparedEventan event to notify the listener that the context has been loaded.
- Function : To prepare the data created above
Phase 3: Refreshing the application context
Execution method:refreshContext(context)
This method is called internally AbstractApplicationContext.refresh(), which is the standard process for initializing the Spring framework container.
- Execution
prepareRefresh()method :- Purpose : Preparatory work before refreshing, such as initializing the property source and validating necessary properties.
- Execution
obtainFreshBeanFactory()method :- Function : To retrieve or refresh internal
BeanFactory(DefaultListableBeanFactory).BeanFactoryIt is the foundation of the Spring container.
- Function : To retrieve or refresh internal
- Execution
prepareBeanFactory(beanFactory)method :- Function : To prepare
BeanFactoryand configure its standard configuration, such as class loader and post-processor.
- Function : To prepare
- Execution
postProcessBeanFactory(beanFactory)method :- Purpose : Allows post-processing after the Bean definition has been loaded but before instantiation
BeanFactory. This is an empty method for subclasses to extend.
- Purpose : Allows post-processing after the Bean definition has been loaded but before instantiation
- Execution
invokeBeanFactoryPostProcessors(beanFactory)method :- Purpose : This is the magic entry point for Spring Boot auto-configuration!
- The most important part is : calling all
BeanFactoryPostProcessor. - Among them,
ConfigurationClassPostProcessorit parses@Configurationthe classes that contain annotations. It will find the annotations on our main class@SpringBootApplication. @SpringBootApplicationIt is included in@EnableAutoConfiguration, and the latter will be importedAutoConfigurationImportSelector.AutoConfigurationImportSelectorItMETA-INF/spring.factorieswill load the auto-configuration classes (e.g. , )EnableAutoConfigurationcorresponding to all keys .DataSourceAutoConfigurationWebMvcAutoConfiguration- These auto-configuration classes determine whether to take effect based on conditions (such as whether a class exists in the classpath, whether a property is set, etc.) and add Bean definitions to the container in batches.
- Execution
registerBeanPostProcessors(beanFactory)method :- Function : Registration
BeanPostProcessor. These processors are called after the bean is instantiated and before and after initialization to enhance the bean (e.g.@Autowired,@PostConstructfeatures such as [list of features] are implemented throughBeanPostProcessor[the process]).
- Function : Registration
- Execution
initMessageSource()method :- Function : Initializes internationalization-related message sources.
- Execution
initApplicationEventMulticaster()method :- Function : Initializes the application event broadcaster for event publishing.
- Execution
onRefresh()method :- Purpose : This is a crucial step in Spring Boot creating and starting an embedded web server!
- In
ServletWebServerApplicationContext[the original text], this method was rewritten. - The most important part is
createWebServer()the method :- The purpose of this method is to obtain (e.g. )
BeanFactoryfrom it .ServletWebServerFactoryTomcatServletWebServerFactory - Calling this
factory.getWebServer(...)method creates an embedded Tomcat/Jetty/Undertow server instance and initializes the Servlet container (initializingDispatcherServletand registering it with the container) . At this point, the web server is created, but it has not yet started listening on the port.
- The purpose of this method is to obtain (e.g. )
- Execution
registerListeners()method :- Function : Register the listener, registering the event listener to the event broadcaster initialized in step 8.
- Execution
finishBeanFactoryInitialization(beanFactory)method :- Purpose : Complete
BeanFactoryinitialization, instantiating all remaining non-lazy-loaded singleton beans. - This is the main phase in which dependency injection occurs within the IoC container. Our Controller, Service, Repository, and other components are created and assembled during this phase.
- Purpose : Complete
- Execution
finishRefresh()method :- Function : To refresh the context and publish the final event.
- The most important part is :
publishEvent(new ContextRefreshedEvent(this)): PublishContextRefreshedEventthe event.ServletWebServerApplicationContextThe process also involves callingfinishRefresh()an extension, which ultimately starts the embedded web server (for example ) and begins listening on the specified port. AtTomcatWebServer.start()this point, our application can handle HTTP requests.
Phase 4: Post-startup processing
- Execution
afterRefresh(context, applicationArguments)method :- Function : Post-refresh processing; defaults to empty. It is an extension point.
- Execution
listeners.started(context)method :- Function : Publishes
ApplicationStartedEventan event to notify all listeners that the application has started.
- Function : Publishes
- Execution
callRunners(applicationArguments)method :- Function : To call
ApplicationRunnerandCommandLineRunnerimplement the interface. - This is a common way for developers to execute specific initialization logic after the application starts but before it begins receiving traffic.
- Function : To call
- Execution
listeners.ready(context, timeTaken)method :- Purpose : Publish
ApplicationReadyEventan event. This event signifies that the application has fully started and is in a ready state .ApplicationStartedEventThe difference between this and [previous event name] is that at this point, all beans have been initialized and the embedded server is running.
- Purpose : Publish
- return
ApplicationContext:- Function : Returns a fully initialized value
ApplicationContext.
- Function : Returns a fully initialized value
Summarize
The entire process main , starting with the method, involves a series of complex and precise steps, including environment preparation, container creation, bean definition loading (auto-configuration), bean instantiation (dependency injection), embedded server startup, and running custom initialization logic . Ultimately, a fully functional Spring Boot application is presented to us. The container refreshContext() is the heart of the entire process, while auto-configuration and the embedded server are key to implementing Spring Boot’s two core features.