Singleton Pattern

March 5, 2026

Singleton Pattern

  • Singleton is a creational design pattern that ensures a class has only one instance and provides a global access.
  • It is typically used for shared resources like configuration, logging, or connection pools.
  • The key implementation: private constructor, providing a static instance, and ensuring thread safety — usually via eager initialization, synchronized access, or double-checked locking.
  • However, Singleton should be used carefully because it introduces global state and can make testing harder (Unit Test).

Singleton (Eage initialization)

Eager initialization (simple & thread-safe)

public class Singleton {
    // Eager initialization (simple & thread-safe)
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() { }  // private constructor

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

Singleton (Lazy initialization)

private static volatile Singleton instance;

public static Singleton getInstance() {
    if (instance == null) {
        synchronized (Singleton.class) {
            if (instance == null) {
                instance = new Singleton();  // double-checked locking
            }
        }
    }
    return instance;
}

Enum Singleton

Recommended / Safest & simplest

public enum Singleton {
    INSTANCE;
    
    // Add your methods here (instance methods)
    public void doSomething() {
        System.out.println("Singleton is doing work...");
    }

    public int compute(int x, int y) {
        return x + y;
    }
}

Usage:

Singleton.INSTANCE.doSomething();          // Access directly via the enum constant
Singleton s1 = Singleton.INSTANCE;
Singleton s2 = Singleton.INSTANCE;
System.out.println(s1 == s2);              // true — always the same instance

In Spring Framework (including Spring Boot), you should almost never implement the classic Singleton design pattern (the GoF one with private constructor + static getInstance()) yourself. It's widely considered an anti-pattern in Spring applications.

1. Spring Already Handles "Singleton" Behavior Perfectly (and Better)

  • By default, every @Component, @Service, @Repository, @Controller, or @Bean is a singleton scope bean.
  • Spring's IoC container creates exactly one instance per application context and shares it everywhere it's injected.
  • This is not the same as the classic Singleton pattern:
    • Spring beans have public constructors (or no-arg if needed).
    • Dependencies are injected explicitly (via constructor, setter, or field) → no hidden global access.
    • Spring manages lifecycle, proxies (if needed), AOP, etc.

Implementing a manual singleton fights against Spring's core strengths (Inversion of Control + Dependency Injection).

2. Classic Singleton Introduces Problems That Spring Avoids

Singleton Problems

3. Best Practice in Spring / Spring Boot (2026)

  • Let Spring manage single instances → annotate with @Service, @Component, etc.
  • Use constructor injection (preferred) for mandatory deps.
  • If you need non-singleton: @Scope("prototype"), @Scope("request"), @Scope("session").
  • For shared stateless services (most common): default singleton scope is ideal and efficient.