Backend Development 16 min read

Understanding the Spring Bean Instantiation Process

This article explains how the Spring IoC container prepares and creates Bean instances, detailing the two main phases—container startup and Bean instantiation—along with the roles of BeanDefinition, BeanFactoryPostProcessor, BeanWrapper, Aware interfaces, BeanPostProcessor, and custom initialization and destruction logic.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Understanding the Spring Bean Instantiation Process

For Java developers, Spring is one of the most popular open‑source frameworks, and beyond enjoying the benefits of the Spring IoC container, it is essential to understand how Spring creates each Bean. This article outlines the Bean instantiation process without diving into source code, focusing on the classes involved and their responsibilities.

Two Phases

Spring manages objects called Beans. The Bean lifecycle can be divided into two phases: the container startup phase and the Bean instantiation phase.

Container Startup Phase

1. Configuration Metadata

Spring needs metadata (XML, properties, annotations, or hard‑coded values) that describe how to create objects. This metadata is called configuration metadata.

<bean id="role" class="com.wbg.springxmlbean.entity.Role">
    <!-- property elements define class attributes
         equivalent to:
         Role role = new Role();
         role.setId(1);
         role.setRoleName("高级工程师");
         role.setNote("重要人员"); -->
    <property name="id" value="1"/>
    <property name="roleName" value="高级工程师"/>
    <property name="note" value="重要人员"/>
</bean>

2. BeanDefinition

All configuration metadata is represented in memory as BeanDefinition objects.

3. BeanDefinitionReader

Different readers (e.g., XmlBeanDefinitionReader, PropertiesBeanDefinitionReader, AnnotatedBeanDefinitionReader) load metadata and convert it into BeanDefinition instances.

4. BeanDefinitionRegistry

The loaded BeanDefinitions are stored in a registry (a key‑value map) that allows the container to locate a definition by its id.

5. BeanFactoryPostProcessor

During startup, BeanFactoryPostProcessor can modify or replace BeanDefinitions, for example to resolve placeholder values such as ${jdbc.url} in the following configuration:

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="maxIdle" value="${jdbc.maxIdle}"/>
    <property name="maxActive" value="${jdbc.maxActive}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

After this phase, the container has a fully prepared set of BeanDefinitions ready for instantiation.

Bean Instantiation Phase

The timing of this phase depends on the chosen loading strategy (eager or lazy). If lazy loading is enabled, Beans remain as definitions until they are requested; otherwise, the container instantiates all Beans immediately after startup.

1. Object Creation Strategy

Spring uses the Strategy pattern to create objects, either via reflection or CGLIB bytecode generation, configurable by the developer.

2. BeanWrapper – The Object’s Wrapper

Every created Bean is wrapped by a BeanWrapper, which simplifies reflective operations such as property access and method invocation.

3. Setting Object Properties

Primitive properties are set directly from metadata; reference properties are injected from already‑created Beans. If a dependency is not yet available, Spring temporarily pauses the current Bean’s creation and resolves the dependency first.

How does Spring solve circular dependencies? It uses a three‑level cache and can only resolve setter‑injection cycles.

4. Aware Interface Checks

If a Bean implements an Aware interface (e.g., ApplicationContextAware), Spring injects the corresponding container object during this step.

5. BeanPostProcessor – Pre‑Initialization

BeanPostProcessor runs before a Bean is placed into the container, allowing modification or replacement of the Bean instance. This is also where AOP proxies are created.

6. Custom Initialization Logic

Developers can define initialization logic via the InitializingBean interface or an init-method attribute.

7. BeanPostProcessor – Post‑Initialization

After custom init logic, BeanPostProcessor can perform additional processing.

8. Custom Destruction Logic

Destruction logic can be provided by implementing DisposableBean or specifying a destroy-method (e.g., closing a DataSource).

9. Usage

Once all steps are complete, the Bean is ready for normal use just like any regular Java object.

10. Destruction Callback

When the container shuts down, Spring invokes the configured destroy callbacks, completing the Bean’s lifecycle.

The bridge between the startup and instantiation phases is the bean’s lazy‑loading strategy; enabling it delays instantiation until the Bean is actually needed.

BackendJavaIoCSpringdependency injectionBean
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

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