Skip to content
Her Tech Corner Her Tech Corner
  • Home
  • Learn Spring
    • Spring Frameworks
    • Java Core
  • Microservices
  • Cloud
  • My Journey
    • Machine Learning
    • Linux
    • Algorithm
    • Book Notes
  • Tools I use
Her Tech Corner
Her Tech Corner

Spring IoC – Understand how Spring initializes beans

Posted on August 5, 2023September 4, 2023 By Hoai Thu

Last updated on September 4th, 2023

Spring is one of the most widely used Java EE frameworks. As with any framework, its utility grows exponentially once you understand its inner workings. At its core, Spring Framework is based on two design principles – Dependency Injection and Aspect Oriented Programming. This post is a note in my series which aims to explore the fundamental concepts of the Spring framework. Let’s figure out the Dependency Injection pattern and how it is applied in Spring Framework.

Table of Contents

Toggle
  • IoC and Dependency injection
  • How Spring initializes beans
  • Next steps

IoC and Dependency injection

IoC – Inversion of Control – is a core pattern applied in the Spring framework. Basically, it is a principle that inverts the control of object creation from our own to an IOC container. We can achieve IoC through various implementations such as Strategy, Factory design pattern, or Dependency Injection pattern. In Spring Framework, we can achieve IoC via Dependency injection implementation.

In Spring, there are three ways of achieving the dependency injection pattern:

  • Constructor injection: for mandatory dependencies or when aiming for immutability.
  • Setter or other methods of injection for optional or changeable dependencies.
  • Through reflection, directly into Field injection.

Constructor injection is considered the best practice in most cases, especially when we aim for immutability. This is because once an object is instantiated, its dependencies cannot be changed. It ensures that all dependencies are available when the bean is created, preventing potential null pointer exceptions. In contrast, Setter and Field injection allow for the modification of dependencies after the object is instantiated, which can make the object’s state unpredictable and harder to maintain. With field injection, dependency problems may not occur until runtime, leading to late error discovery.

The advantages of this architecture are:

  • Decoupling: Dependency injection promotes loose coupling between components by allowing the dependencies of a class to be provided by a container, rather than the class itself instantiating the dependent objects. This approach makes it easier to switch between different implementations or modify the dependencies without changing the class code.
  • Separation of concerns: components should focus only on the core business logic, and not on creating or managing its dependencies.
  • Testability: dependencies being mocked easily, can test individual components in isolation.

How Spring initializes beans

The interface ApplicationContext represents the IoC container in Spring. The Spring container is responsible for managing the application components by creating objects, wiring them together along with configuring and managing their overall life cycle.

This is a high-level overview of how Spring wires beans under the hood:

Spring life cycle

Basically, Spring implements IoC by using Java Reflection API, proxies, and a variety of other techniques to create, wire, and manage the beans’ lifecycle.

  • Bean scanning: When the Spring application starts, it scans the classes and configuration files to create bean definitions. A BeanDefinition contains metadata about the bean class, such as constructor, initialization methods, dependencies, and scope. These BeanDefinition objects are internally registered by BeanDefinitionRegistry which is used by the IoC container later to instantiate and manage the beans.
  • Bean instantiation: Then, using Reflection API, Spring instantiates the bean by calling the constructor or the factory method specified in the BeanDefinition. Note: before bean instantiation, BeanFactoryPostProcessors will be called. It can modify or transform BeanDefinitionprior to instantiation. A most familiar example BeanFactoryPostProcessors is PropertySourcesPlaceholderConfigurer to load properties files at one point.
  • Bean dependencies: Once the bean is instantiated, Spring populates its dependencies by either setter injection, field injection, or constructor injection. It uses the Reflection API to set values, invoke setter methods, or pass them as constructor arguments. If the dependencies are defined in XML configuration, Spring converts them from their string representation to their required target types by using PropertyEditors or Converters.
  • Bean post-processing: Then, Spring applies registered BeanPostProcessors to perform additional customizing or manipulating the bean. For example, proxies for AOP, transaction management, and caching are being created and applied during this stage.
  • Bean initialization and destruction: Spring calls @PostConstruct, InitializingBean interfaces or custom init-method after all the properties and dependencies have been set. Once the bean is no longer required and the context is being closed, Spring calls the appropriate destruction callback such as @PreDestroy, DisposableBean interfaces or custom destroy-method.

Next steps

We’ve covered the core of Spring Framework. To me, grasping the underlying theory before starting code is extremely important. To further expand your knowledge, you can explore the AOP concept in this article and stay tuned for my upcoming post on Spring design patterns. However, true learning often comes from hands-on experience, so be sure to put theory into practice as you continue your journey with the Spring Framework.

Related

Spring Frameworks Design PatternSpring

Post navigation

Previous post
Next post

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Categories

  • Algorithm (2)
  • Cloud (1)
  • Database (1)
  • Java Core (1)
  • Learn Spring (1)
  • Machine Learning (1)
  • Microservices (4)
  • Spring Frameworks (6)
  • Tools I use (1)

Recent Posts

  • Leetcode challenges 2023-2024December 12, 2023
  • Docker Essentials: A Novice’s JourneyOctober 7, 2023
  • Spring Cloud Gateway as an OAuth2 ClientSeptember 25, 2023
  • An Introduction to Prompt Engineering with LLMsSeptember 18, 2023
  • A brief overview of API Gateway Pattern in MicroservicesSeptember 7, 2023

Tags

Algorithms AOP API Gateway Authorization Server Cloud Database Design Pattern Docker Java8 Jwt Leetcode LLMs Microservices Oauth2 Prompt Refactoring Spring

©2025 Her Tech Corner | WordPress Theme by SuperbThemes