Understanding Spring's Three-Level Cache Mechanism
The article explains Spring's three-level cache design—including singletonObjects, earlySingletonObjects, and singletonFactories—how it resolves circular bean dependencies, enables lazy initialization and proxy creation, outlines the workflow, and discusses its limitations and practical solutions.
In the Spring framework, the three-level cache mechanism is a sophisticated design that plays a crucial role in handling complex bean dependencies and initialization issues within Spring applications.
What is the three-level cache? It is a caching strategy introduced to address circular dependencies during singleton bean creation. The cache consists of three layers:
Level 1 cache (singletonObjects) stores fully initialized singleton beans ready for use, implemented with ConcurrentHashMap . When the container needs a bean, it first checks this cache.
Level 2 cache (earlySingletonObjects) also uses ConcurrentHashMap to hold bean instances that have been instantiated but not yet fully initialized, allowing other beans to obtain a temporary reference during circular dependency resolution.
Level 3 cache (singletonFactories) stores ObjectFactory objects, which can create singleton bean instances on demand, supporting more complex dependency scenarios and lazy initialization.
Why introduce a three-level cache? It solves circular dependency problems by exposing bean references before full initialization, preventing infinite recursion and StackOverflowError . It also enables lazy initialization and the creation of proxy objects (e.g., AOP proxies) via the singletonFactories layer.
When is the three-level cache triggered? It activates when a circular dependency is detected during singleton bean creation, or when lazy initialization or proxy creation is required under specific conditions.
Workflow of the three-level cache:
1. Bean creation request : The container checks Level 1; if the bean is fully initialized, it returns it.
2. Check Level 2 : If not in Level 1, the container looks in Level 2. If found, the partially initialized bean is returned to dependent beans.
3. Create temporary instance and put into Level 3 : If absent in Level 2, a temporary bean is created, wrapped in an ObjectFactory , and stored in Level 3.
4. Continue creation and resolve circular dependencies : During further creation, the container may retrieve the ObjectFactory from Level 3 to obtain or create dependent beans, breaking the circular chain.
5. Complete initialization : Once a bean is fully created, it is moved to Level 1 for future direct access.
Limitations : Constructor injection cannot be resolved by the three-level cache because dependencies must be satisfied at instantiation time. In such cases, Spring throws BeanCurrentlyInCreationException .
Solutions :
1. Use setter or field injection, or combine with @Lazy for delayed initialization.
2. Create proxy objects (e.g., using AopProxy ) and inject the proxy instead of the real bean.
3. Adjust dependency order with @DependsOn to enforce a specific bean loading sequence.
Conclusion : Spring's three-level cache intelligently manages bean creation, effectively resolves circular dependencies, and supports lazy initialization and proxy creation, making the framework more efficient and flexible for building complex backend applications.
Cognitive Technology Team
Cognitive Technology Team regularly delivers the latest IT news, original content, programming tutorials and experience sharing, with daily perks awaiting you.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.