Beans, Configuration & Lifecycle
"Bean" gets thrown around from your first day with Spring. This module is precisely what one is, how it's born, and how it dies.
Learning objectives
- Beginner: Recognize that "bean" just means "an object the container manages," not special new syntax.
- Intermediate: Choose correctly between @Component-style and @Bean-method declaration depending on whether you own the class being registered.
- Advanced: Predict and control lifecycle ordering issues (e.g. a bean depending on another bean that isn't ready yet) using @PostConstruct and lifecycle callbacks.
A bean is simply an object whose lifecycle — creation, dependency injection, initialization, and destruction — is managed by the ApplicationContext instead of your own code. There's no special Bean base class or interface required; almost any plain Java object can become a bean the moment the container is told to manage it.
// 1. Component scanning — annotate the class itself, container discovers it @Service public class BookService { } // 2. Explicit @Bean method — for classes you don't own (can't annotate a 3rd-party class) @Configuration public class AppConfig { @Bean public ObjectMapper objectMapper() { return new ObjectMapper().registerModule(new JavaTimeModule()); } }
Component scanning (Module 04's stereotype annotations) is the default for your own application classes. Explicit @Bean methods inside an @Configuration class are for anything you can't annotate directly — third-party library classes, or a bean that needs custom construction logic.
💻 Code example
// 1. Component scanning — annotate the class itself, container discovers it @Service public class BookService { } // 2. Explicit @Bean method — for classes you don't own (can't annotate a 3rd-party class) @Configuration public class AppConfig { @Bean public ObjectMapper objectMapper() { return new ObjectMapper().registerModule(new JavaTimeModule()); } }
| Scope | Lifetime |
|---|---|
| singleton (default) | Exactly one instance per container, shared by every class that injects it. |
| prototype | A new instance is created every time the bean is requested/injected. |
| request (web apps) | One instance per HTTP request. |
| session (web apps) | One instance per HTTP session. |
▲ Pitfall
The default singleton scope means a single shared instance handles every concurrent request — any mutable instance field on a singleton-scoped @Service is effectively shared, unsynchronized state across every simultaneous user, a common source of subtle concurrency bugs for developers assuming each request gets its own object.
The container instantiates a bean, injects its dependencies, runs any @PostConstruct initialization, keeps it alive for the application's lifetime (for a singleton), then runs @PreDestroy on shutdown.
@Service public class CacheWarmerService { @PostConstruct public void warmCache() { // runs once, right after dependency injection completes } @PreDestroy public void cleanup() { // runs once, during graceful application shutdown } }
◆ Under the hood — why lifecycle order matters
@PostConstruct is guaranteed to run only after all of a bean's dependencies have been injected — this is precisely why it's the right place for initialization logic that depends on an injected collaborator being non-null, rather than putting that logic directly in the constructor, where a field injection dependency (Module 02 §3) might not yet be set.
✓ Quick recap
Does a class need to implement a special interface to become a bean? No — almost any plain Java object can be managed as a bean once the container is told about it, via component scanning or an @Bean method. What's the risk of mutable instance fields on a default-scoped (singleton) service? They're shared, unsynchronized state across every concurrent request handled by that single instance.
💻 Code example
@Service public class CacheWarmerService { @PostConstruct public void warmCache() { // runs once, right after dependency injection completes } @PreDestroy public void cleanup() { // runs once, during graceful application shutdown } }
Want a visual for this concept?
Generate a diagram tailored to “Beans, Configuration & Lifecycle” — the AI picks whichever visual (flowchart, comparison, sequence, etc.) best fits.
Sign in to generate a visual →