Bean Lifecycle & Scopes
What Is a Spring Bean?
A Spring bean is an object that is created, managed, and destroyed by the Spring IoC container. Every class marked with a stereotype annotation (@Component, @Service, @Repository, etc.) is a Spring bean.
Bean Creation Lifecycle
Here are the stages when Spring creates a bean:
1. Container detects the class definition
2. Create an instance (constructor)
3. Set properties (dependency injection)
4. Call @PostConstruct
5. Bean is ready to use
6. (at shutdown) Call @PreDestroy
7. Bean is destroyed
Lifecycle Callback Example
@Component
public class DatabaseMonitor {
@PostConstruct
public void init() {
// Called AFTER the bean is created and its dependencies are injected
System.out.println("DatabaseMonitor initialized");
}
@PreDestroy
public void cleanup() {
// Called BEFORE the bean is destroyed by the container
System.out.println("DatabaseMonitor destroyed");
}
}
Full Order
| Stage | Description |
|---|---|
| Instantiation | Constructor is called |
| Populate properties | @Autowired is resolved |
| BeanNameAware | If it implements BeanNameAware |
| BeanFactoryAware | If it implements BeanFactoryAware |
@PostConstruct |
Post-initialization hook |
| Ready to use | Bean is active in the container |
@PreDestroy |
Pre-destruction hook |
Bean Scopes
A scope determines how many instances of a bean are created and when they are used.
| Scope | Number of Instances | When Created |
|---|---|---|
| singleton | 1 per container | When the container starts (default) |
| prototype | Many (per request) | Every time it's requested |
| request | 1 per HTTP request | Per HTTP request |
| session | 1 per HTTP session | Per user session |
Singleton (Default)
@Component // Default: singleton
public class UserService {
// Only 1 instance across the entire application
}
Prototype
@Component
@Scope("prototype")
public class ShoppingCart {
// Every @Autowired creates a new instance
}
Request & Session (Web)
@Component
@RequestScope // Shorthand for @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class RequestContext {
private String ipAddress;
}
@Component
@SessionScope
public class UserSession {
private String username;
}
@Scope Annotation
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TaskExecutor {
// Prototype scope using a constant
}
Lazy Initialization
By default, Spring creates all beans at startup (eager initialization). With @Lazy, a bean is created the first time it's accessed:
@Component
@Lazy
public class ExpensiveReportGenerator {
public ExpensiveReportGenerator() {
// Constructor is not called at startup
// It's called the first time the bean is injected/accessed
System.out.println("ReportGenerator created on demand");
}
}
Enable lazy loading globally in application.properties:
spring.main.lazy-initialization=true
| Type | Startup Time | Memory Usage | First Access |
|---|---|---|---|
| Eager (default) | Longer | Higher | Available immediately |
| Lazy | Faster | Lower | Delay on the first access |
Summary
| Concept | Description |
|---|---|
| Bean | Object managed by the Spring container |
| Singleton | 1 instance (default) |
| Prototype | New instance per request |
@PostConstruct |
Initialization after DI |
@PreDestroy |
Cleanup before destruction |
@Lazy |
Create the bean when it's first needed |
With an understanding of the bean lifecycle and scopes, you can control how Spring manages the objects in your application. In the next chapter, we'll put it all into practice: building a first REST API with Spring Boot.