Drawbacks of the Singleton pattern
Fast recall
Quick revision
Core answer
getInstance() (you can't see them in the constructor), makes testing hard via shared global state, often holds global mutable state needing tricky synchronization, and violates SRP by mixing logic with lifecycle control. Spring's dependency injection fixes these by moving lifecycle to the container and making dependencies explicit.Interview-ready guide
Interview answer
Singleton has several serious problems that make it an anti-pattern in many situations.
The biggest is hidden dependencies. When a service calls ConfigManager dot getInstance, you can't tell from the constructor what the class depends on — the dependency is invisible, which makes the code harder to understand and maintain. It also makes testing painful, because to test that service with fake configuration you can't easily inject a substitute; you'd have to use reflection or a tool like PowerMock, which are red flags.
Another problem is global mutable state. If the Singleton has fields that change, like the current user or active session, multiple threads access and modify that shared state concurrently, so you need complex synchronization and it's easy to introduce race conditions. Singleton also violates the Single Responsibility Principle, because the class is responsible both for its business logic and for managing its own lifecycle — two different concerns mixed together.
And in Spring applications, hand-rolling a Singleton fights the framework, since Spring already gives you singleton-scoped beans with the benefits and none of the drawbacks.
The key insight to leave them with is that dependency injection solves Singleton's problems by externalizing lifecycle management: you still get a single instance when you want one, but the dependency is explicit in the constructor and easy to mock, so your tests stay isolated and deterministic.
Drawbacks of the Singleton pattern
Direct Answer
Singleton's problems: it hides dependencies behind static getInstance() (you can't see them in the constructor), makes testing hard via shared global state, often holds global mutable state needing tricky synchronization, and violates SRP by mixing logic with lifecycle control. Spring's dependency injection fixes these by moving lifecycle to the container and making dependencies explicit.
Deep Dive & Architecture
Singleton is a creational pattern that guarantees a class has exactly one instance and gives a global access point to it.
You enforce it with a private constructor, a static instance field, and a static getInstance().
It's for shared resources — connection pools, config, logging — where extra instances waste resources or split state. The fresher trap: it must be thread-safe.
Writing a plain null-check without synchronization, letting two threads create two instances
Common Mistakes & Pitfalls
- Treating Singleton as a default. Most objects should have many instances; not everything needs to be unique.
- Tests that share Singleton state — they become order-dependent and flaky.
- Ignoring Spring alternatives — manual
getInstance()in a Spring app reinvents what@Servicealready does, worse. - Mutable fields in a Singleton — concurrency bugs across threads serving different users.
Check your understanding
Answer these without looking back at the article.
- What is the Singleton design pattern?
- How does Spring Boot implement Singleton scope for beans?
- What is the enum-based Singleton in Java and why is it preferred?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.