Overview

This article deeply analyzes the Spring IoC container system, covering BeanFactory process analysis and Bean lazy loading mechanism.

BeanFactory

Sub-Process Key Steps

Resource Location: The process of locating BeanDefinition resources, which is the XML file containing JavaBean information, encapsulated as a Resource object.

BeanDefinition Loading: Converting user-defined JavaBeans into the internal data structure of the IoC container. This internal data structure is the BeanDefinition.

Process Analysis

The sub-process entry is in the AbstractRefreshableApplicationContext#refreshBeanFactory method.

loadBeanDefinitions(beanFactory): Loads BeanDefinitions from the application, calling multiple class loadBeanDefinitions methods in sequence:

  • Step 1: AbstractXmlApplicationContext
  • Step 2: AbstractBeanDefinitionReader
  • Step 3: XmlBeanDefinitionReader
  • Step 4: XmlBeanDefinitionReader’s doLoadBeanDefinition method

Key observation is on the registerBeanDefinition method in the XmlBeanDefinitionReader class, during which multiple overloaded calls occur. Then it goes to createReaderContext function, and subsequently to DefaultNamespaceHandlerResolver, completing NamespaceHandlerResolver initialization.

In DefaultBeanDefinitionDocumentReader, find the registerBeanDefinition method. According to doRegisterBeanDefinitions, parseBeanDefinition is called. The process of parsing Bean elements is at processBeanDefinition, and BeanDefinitionReaderUtils.registerBeanDefinition completes the Bean registration.

Bean

The Bean creation sub-process entry is at AbstractApplicationContext#refresh() method’s finishBeanFactoryInitialization(beanFactory).

Following it, you can see preInstantiateSingletons at the end, which instantiates all immediately-loaded singleton Beans. Following further, you find that all are instantiated through the getBean method.

Lazy-init

The lazy loading mechanism: ordinary Bean initialization runs during container initialization phase, while Beans modified with lazy-init=true are triggered from the first context.getBean execution.

When Spring starts, it parses all Bean information (including XML and annotations), converts it into BeanDefinition that Spring can recognize, and stores it in a HashMap for subsequent initialization use. Then each BeanDefinition is processed. If it’s lazy-loaded, it’s not processed during container initialization; others are initialized during container initialization for dependency injection.