What is a Registry-based Singleton Design Pattern?
A Registry-Based Singleton is an advanced Singleton implementation where multiple singleton instances are stored in a central registry (map or cache), allowing controlled access to different singleton objects.
Instead of restricting the class to a single instance, this pattern allows managing multiple named singletons efficiently.
Why Use a Registry-Based Singleton?
- manage multiple Singletons – Instead of a single instance, it maintains a registry of multiple singleton instances.
- Flexible and Scalable – Supports multiple singleton types or named instances.
- Reduces Hard-Coded Dependencies – Avoids tight coupling by using dynamic lookups.
- Good for Distributed Systems – It can be used to manage singleton instances across multiple services.
Advantages of Registry-Based Singleton
- Multiple Singleton Objects – Unlike traditional Singleton, this allows multiple singletons.
- Global Access – All registered singletons can be accessed dynamically.
- Thread-Safe – Uses ConcurrentHashMap, ensuring thread safety.
- More Flexible – Easy to extend by adding more singleton instances dynamically.
Disadvantages of Registry-Based Singleton
- Memory Overhead – Stores multiple objects in memory, unlike a classic Singleton.
- Manual Registration Needed – Each singleton must be explicitly registered.
- Possible Memory Leaks – If objects are not deregistered properly, they may persist unnecessarily.
Use Cases of Registry-Based Singleton
- Configuration Management – Stores multiple configuration objects for different modules.
- Database Connection Pooling – Manages multiple database connection instances.
- Service Locators – Used to fetch singleton service objects dynamically.
- Plugin Systems – Dynamically loads and registers singleton plugin instances.
Brief Description of Implementation
I have developed a small program to understand the Registry-based Singleton Design Pattern by using Map, ConcurrentHashMap to store and retrieve the Singleton instances dynamically.
1st Step, I have created a Registry class named RegistrySingleton.java where I have used a ConcurrentHashMap to store the Singleton objects.
public class RegistrySingleton {
private static final Map<String, Object> registry = new ConcurrentHashMap<>();
private RegistrySingleton() {}
public static void registerInstance(String key, Object instance) {
if(!registry.containsKey(key)) {
registry.put(key, instance);
}
}
public static Object getInstance(String key) {
return registry.get(key);
}
}
2nd Step, I have created 2 singleton classes named Spring.java and Struts.java.
public class Spring {
private static final Logger LOG = LoggerFactory.getLogger(Spring.class);
private static Spring spring;
private Spring() {}
public void dependencyInjection() {
LOG.info("Spring MVC Framework : {}", spring.hashCode());
}
public static Spring getInstance() {
if(null == spring) {
spring = new Spring();
}
return spring;
}
}
public class Struts {
private static final Logger LOG = LoggerFactory.getLogger(Struts.class);
private static Struts struts;
private Struts() {}
public void xmlBasedConf() {
LOG.info("Struts MVC Framework : {}", struts.hashCode());
}
public static Struts getInstance() {
if(null == struts) {
struts = new Struts();
}
return struts;
}
}
3rd Step, Now in this step I have registered the above singleton classes and used those singleton classes object’s methods.
public class RegistrySingletonMasterclassApplication {
private static final Logger LOG = LoggerFactory.getLogger(RegistrySingletonMasterclassApplication.class);
public static void main(String[] args) {
RegistrySingleton.registerInstance("SPRING", Spring.getInstance());
RegistrySingleton.registerInstance("STRUTS", Struts.getInstance());
Spring spring = (Spring) RegistrySingleton.getInstance("SPRING");
spring.dependencyInjection();
LOG.info("HashCode of Spring instance: {}", spring.hashCode());
Struts struts = (Struts) RegistrySingleton.getInstance("STRUTS");
struts.xmlBasedConf();
LOG.info("HashCode of Struts instance: {}", struts.hashCode());
}
}
I have provided the log below to verify whether the objects created and stored in ConcurrentHashMap are the same or not.
INFO com.springcavaj.designpattern.singleton.registry.design.Spring - Spring MVC Framework : 2047329716
INFO com.springcavaj.designpattern.singleton.registry.RegistrySingletonMasterclassApplication - HashCode of Spring instance: 2047329716
INFO com.springcavaj.designpattern.singleton.registry.design.Struts - Struts MVC Framework : 96639997
INFO com.springcavaj.designpattern.singleton.registry.RegistrySingletonMasterclassApplication - HashCode of Struts instance: 96639997
Steps to run the application
The complete Run application steps are provided in this README.md file, but still, I am providing the steps to run points below.
- Clone the sprincavaj-designpattern application from the GitHub repository.
- Import the application as a Maven application, either in STS or Eclipse.
- Find the RegistrySingletonMasterclassApplication.java class.
- Right-click on the file and select Run As -> Java Application.