Dung (Donny) Nguyen

Senior Software Engineer

Bean

In Spring, a Bean is an object that is instantiated, assembled, and managed by the Spring IoC container. The IoC container is responsible for creating and managing the lifecycle of these Beans. Some key characteristics of Beans in Spring:

  1. Instantiation: The IoC container is responsible for instantiating Beans. It creates the objects based on the configuration, which can be XML, Java annotations, or a combination of both.

  2. Dependency Injection: The IoC container is also responsible for injecting the necessary dependencies into a Bean. This is the “Inversion of Control” part, where the container manages the dependencies instead of the Bean itself.

  3. Lifecycle Management: The IoC container manages the entire lifecycle of a Bean, from creation to destruction. It can perform tasks like initializing and destroying Beans as needed.

  4. Scope: Beans can have different scopes, such as singleton (one instance per Spring IoC container), prototype (a new instance for each request), request, session, and application. The scope determines how the IoC container manages the Bean instances.

  5. Configuration: Beans are configured either through XML configuration files or Java-based configuration using annotations like @Configuration and @Bean.

Beans are the fundamental building blocks of any Spring application. They encapsulate the business logic and are wired together by the IoC container to create a complete application. The container’s ability to manage Beans and their dependencies is a core part of the Spring framework’s architecture and functionality.

Ways to Define a Bean

Spring offers several approaches to declare a Bean. The most common ones in modern applications are annotation-based.

1. Stereotype Annotations (Component Scanning)

When a class is annotated with @Component or one of its specializations, Spring automatically detects and registers it as a Bean during component scanning.

@Component
public class EmailService {
    public void send(String message) {
        // send email
    }
}

The common stereotype annotations are:

2. The @Bean Method in a Configuration Class

Use @Bean inside a @Configuration class when you need full control over how the object is created — for example, when configuring third-party classes you cannot annotate.

@Configuration
public class AppConfig {

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

3. XML Configuration (Legacy)

Older applications define Beans in an XML file. This style is rarely used in new projects but is still found in legacy systems.

<beans>
    <bean id="emailService" class="com.example.EmailService"/>
</beans>

Bean Scopes in Detail

The scope controls how many instances of a Bean the container creates and how long they live.

Scope Description
singleton (default) A single shared instance per Spring IoC container.
prototype A new instance is created every time the Bean is requested.
request One instance per HTTP request (web-aware contexts only).
session One instance per HTTP session (web-aware contexts only).
application One instance per ServletContext (web-aware contexts only).
websocket One instance per WebSocket session.
@Component
@Scope("prototype")
public class ReportGenerator {
    // a new instance is created on each request
}

Bean Lifecycle

The IoC container manages a Bean through the following phases:

  1. Instantiation — the container creates the Bean instance.
  2. Populate properties — dependencies are injected.
  3. Initialization callbacks — methods annotated with @PostConstruct, or an afterPropertiesSet() from InitializingBean, or a custom initMethod are invoked.
  4. Bean is ready — the Bean is available for use in the application.
  5. Destruction callbacks — on container shutdown, methods annotated with @PreDestroy, or destroy() from DisposableBean, or a custom destroyMethod are invoked (applies to singleton Beans).
@Component
public class CacheManager {

    @PostConstruct
    public void init() {
        // warm up the cache after dependencies are injected
    }

    @PreDestroy
    public void cleanup() {
        // release resources before the Bean is destroyed
    }
}

How Beans Are Wired Together

Beans rarely work in isolation. The container injects one Bean into another so they can collaborate. Constructor injection is the recommended approach because it promotes immutability and makes dependencies explicit.

@Service
public class OrderService {

    private final EmailService emailService;

    public OrderService(EmailService emailService) {
        this.emailService = emailService;
    }

    public void placeOrder() {
        // business logic
        emailService.send("Order confirmed");
    }
}

Summary

A Bean is simply a Java object whose creation, configuration, dependencies, and lifecycle are handled by Spring instead of your code. By letting the container manage these concerns, you get loosely coupled, testable, and maintainable applications. Understanding how Beans are defined, scoped, wired, and destroyed is essential to working effectively with the Spring framework.