π§© Spring Bean Anatomy β Definition, Scope, Proxy, and Lifecycle Hooks¶
Essence: A Spring Bean is a managed Java object whose creation, wiring, lifecycle, and sometimes even identity are controlled by the Spring container β not by your code. Itβs a living object with metadata, behavior, and reflective wrapping.
π± The Mental Model¶
A bean in Spring is to the container what a cell is to an organism: it has a definition (DNA), a lifecycle (birth β death), and a membrane (proxy) that controls how it interacts with the outside world.
𧬠1. Bean Definition β the DNA¶
Before a bean exists, Spring builds a BeanDefinition β metadata describing how to create it.
Each definition contains:
| Field | Description |
|---|---|
beanClass |
The Class<?> object of the bean |
scope |
"singleton", "prototype", "request", etc. |
dependencies |
Other beans to inject |
initMethod, destroyMethod |
Lifecycle callbacks |
lazyInit |
Whether to delay creation until needed |
primary, qualifiers |
Conflict resolution hints |
The BeanDefinition lives in memory long before any object is created.
βοΈ 2. Instantiation β the Birth¶
When the context is refreshed, Spring instantiates the bean via reflection:
Then it resolves all declared dependencies (@Autowired, constructor args, etc.).
At this point:
- The object exists.
- Dependencies are injected.
- Lifecycle callbacks havenβt yet run.
This is the infant bean stage.
π§© 3. Initialization β Becoming Alive¶
Spring then applies post-processing and lifecycle interfaces:
| Mechanism | Trigger | Purpose |
|---|---|---|
@PostConstruct |
Annotation | Custom setup logic |
InitializingBean.afterPropertiesSet() |
Interface | Legacy init hook |
init-method |
XML config | Alternative init |
BeanPostProcessor |
Global interceptors | Modify/replace beans after creation |
For example, a post-processor might wrap a bean in a proxy to add behavior (@Transactional, @Async, etc.).
After initialization, the bean is fully active β ready to be used or injected elsewhere.
πͺ 4. Proxies β The Membrane¶
A proxy is a thin reflective wrapper around your bean. It intercepts method calls to add extra logic like transactions, security, or async execution.
Two main types:¶
| Type | Tool | Used For |
|---|---|---|
| JDK Dynamic Proxy | Javaβs Proxy API |
Interfaces only |
| CGLIB Proxy | Bytecode subclass | Concrete classes |
Example:
Spring replaces it at runtime with something like:
When you call a method, the proxy runs code before and after your logic (start transaction β invoke target β commit/rollback).
π§ 5. Scopes β The Lifecycle Context¶
A beanβs scope defines how long it lives and where itβs shared:
| Scope | Description |
|---|---|
singleton |
One shared instance per context (default) |
prototype |
New instance every injection |
request |
One per HTTP request (web only) |
session |
One per HTTP session |
application |
One per servlet context |
websocket |
One per WebSocket session |
Example:
@Autowired of a prototype bean creates a fresh instance each time.
π§© 6. Awareness Interfaces β Talking to the Container¶
Some beans want to βknowβ about their environment. Spring injects this information through special Aware interfaces:
| Interface | What you get |
|---|---|
ApplicationContextAware |
Access to the context |
BeanNameAware |
The name assigned to your bean |
EnvironmentAware |
Config and property access |
ResourceLoaderAware |
File/resource utilities |
These arenβt common for business logic, but essential for infrastructure beans (framework internals, logging, plugin systems).
π 7. Destruction β Graceful Death¶
At shutdown or when the context closes:
| Mechanism | When |
|---|---|
@PreDestroy |
Before bean destruction |
DisposableBean.destroy() |
Legacy cleanup |
destroy-method |
XML config |
ContextClosedEvent |
Published globally |
Spring calls these hooks reflectively to release connections, threads, caches, etc.
π§© 8. The Full Lifecycle Map¶
1. Scan classes β build BeanDefinition
2. Instantiate β inject dependencies
3. Apply BeanPostProcessors
4. Call @PostConstruct / init-method
5. Bean ready for use
6. (Optionally) wrapped in proxy
7. Serve requests or logic
8. Context shutdown β call @PreDestroy
β‘ Putting it Together β Reflectionβs Thread¶
Reflection appears at every layer:
- Definition stage: reads annotations (
Class.isAnnotationPresent) - Instantiation stage: calls constructors
- Injection stage: sets fields or methods
- Initialization stage: invokes annotated methods
- Proxying stage: intercepts via dynamic subclasses
Yet once the bean is active, reflection disappears β normal method calls dominate.
π§ TL;DR Summary¶
| Aspect | Description | Driven by Reflection? |
|---|---|---|
| Definition | Metadata blueprint | β |
| Instantiation | Create object | β |
| Injection | Wire dependencies | β |
| Post-processing | Modify or proxy | β |
| Active state | Business logic | β |
| Destruction | Cleanup hooks | β |
πͺ Core takeaway¶
A Spring Bean is not just an object β itβs a meta-object, born from metadata, shaped by reflection, guarded by proxies, and governed by lifecycle rules. Once awakened, it becomes indistinguishable from plain Java β until the next context refresh.