Spring IOC – Spring startup process analysis

The core logic of the Spring startup process is mainly reflected in the method AbstractApplicationContext#refresh, which has not been overridden by subclasses.

This article mainly analyzes it from a macro level and perceives it as a whole. The execution steps and functions are shown in the table below in order. The methods marked in red are the core methods, and the methods marked in green provide expansion points.

method name

main effect

prepareRefresh()

Record container startup time and set container status; provide extension points for customizing key-value attributes

obtainFreshBeanFactory()

Get a fresh beanFactory instance, this method is implemented by two subclasses:

1.GenericApplicationContext: Very simple, returns the beanFactory created by the parameterless constructor

2.AbstractRefreshableApplicationContext: Close the current beanFactory and create a new beanFactory, reflecting the meaning of refresh

prepareBeanFactory(beanFactory)

Insert bean instances into beanFactory in advance: such as BeanFactory, ResourceLoader, etc., and set up class loaders, property editors, etc.

postProcessBeanFactory(beanFactory)

This is an extension point left by Spring. The purpose is to leave the user to make some final settings on the beanFactory after the beanFactory is ready.

For example, for web applications, after rewriting, insert singleton beans such as ServletContext into the beanFactory.

invokeBeanFactoryPostProcessors(beanFactory)

Call the implementation class of BeanFactoryPostProcessor to perform post-processing on BeanFactory, such as calling ConfigurationClassPostProcessor to parse common annotations and generate BeanDefinition

registerBeanPostProcessors(beanFactory)

Register Bean post-processors, including system built-in and customized ones, such as: AutowireAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor

initMessageSource()

Initialize MessageSource to support internationalization

initApplicationEventMulticaster()

Initialize event dispatcher to support event listening

onRefresh()

The extension points provided by Spring are left to subclasses to implement.

registerListeners()

Register event listener

finishBeanFactoryInitialization(beanFactory)

Instantiate all non-lazy-loaded singleton beans. The life cycle of Spring Bean starts here.

finishRefresh()

Complete the refresh, publish the container refresh completion event, etc.

The source code and comments are as follows:

 // The core method of Spring application context, which is responsible for completing the initialization and refreshing of the Spring container
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// Prepare for refresh operation, including recording container startup time, setting container status, obtaining attributes, and verifying necessary attributes
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
// Get a fresh BeanFactory instance, this method is implemented by the subclass
// Get the new beanFactory, destroy the original beanFactory, generate BeanDefinition for each bean, etc. Note that here we get the new one and destroy the old one. This is the meaning of refreshing.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
// Make some settings for the BeanFactory, such as setting the class loader, adding a property editor, etc.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
//Allow subclasses to further process the BeanFactory after its standard initialization is completed.
// This is the extension point left by spring. Currently, after the beanFactory is ready, it is left to the user to make some final settings on the beanFactory.
// Please refer to GenericWebApplicationContext#postProcessBeanFactory for implementation
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
// Call the implementation class of BeanFactoryPostProcessor to post-process BeanFactory
// Scan and parse the core code
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
//Register the implementation class of BeanPostProcessor for interception during Bean creation process
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
//Initialize MessageSource to support internationalization
initMessageSource();

// Initialize event multicaster for this context.
//Initialize event dispatcher to support event monitoring
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
//Leave it to subclasses for special processing when the container is refreshed
onRefresh();

// Check for listener beans and register them.
//Register event listener
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// Instantiate all non-lazy loaded singleton beans
// This step can be said to have the most contact with our developers. Most of our customized beans are initialized in this step, including dependency injection and so on.
// Therefore, understanding this step can give us a deeper understanding of how Spring manages the life cycle and dependencies of our Beans.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
// Complete the refresh operation, including publishing container refresh completion events, etc.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
// If an exception occurs during the refresh process, this method will be executed to cancel the operation and destroy the created singleton beans. Finally, some caches in the Spring core will be reset.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}