From what I understand, a singleton is basically when you have a private member that represents the object you want to have a single instance for. Then in the constructor you initialize the member object.
All references for this object are done via a public property, and the public property just references the private member that has already been instantiated.
Now in a web application, how does this work? Does a single instance just hang around in the container (say tomcat) until tomcat is shutdown?
The most popular approach is to implement a Singleton by creating a regular class and making sure it has: A private constructor. A static field containing its only instance. A static factory method for obtaining the instance.
I would argue the most common way to implement a singleton is to use an enum with one instance. That might be a "better" way but definitely not the most common way. In all the projects I have worked on, Singletons are implemented as I have shown above.
Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.
A singleton is a class that allows only a single instance of itself to be created and gives access to that created instance. It contains static variables that can accommodate unique and private instances of itself. It is used in scenarios when a user wants to restrict instantiation of a class to only one object.
If your execution environment uses multiple class loaders, then you get one singleton per instance of your class. If your singleton class is loaded into different class loaders, then it's actually two distinct classes and then there will be two "singleton" instances.
You can find some info on the Tomcat class loaders in the documentation.
A distinction should be made between the Singleton pattern, and its implementation. Most if not all common Singleton implementations suffer from the mentioned problems with classloading as well as serialization, thread safety etc. See https://www.securecoding.cert.org/confluence/display/java/MSC07-J.+Prevent+multiple+instantiations+of+singleton+objects for a quite thorough overview.
However, the Singleton pattern in its broadest sense can be any service guaranteed to be unique within a certain context. The uniqueness of a Singleton can only be specified relative to a given scope like a classloader, JVM, container or cluster; the level of uniqueness depends on the implementation, which should be chosen based on the application's requirements.
Two very common requirements leading to the use of Singletons are dependency injection (c.q. using a factory) and in-memory caching. In both cases there are good frameworks that hide the Singleton aspect from the client and offer a sufficient level of uniqueness within for instance an enterprise application container. For dependency injection Spring, Guice or Pico come to mind. For caching I know Ehcache as leading solution, but there are certainly more out there. (fun trivia: The name 'ehcache' is a palindrome)
In general, use of Singletons is 'frowned upon', and seen as an anti-pattern. On the other hand, services like dependency injection and caching require uniqueness to work. So we are fooling ourselves a bit if we proclaim to be anti-Singleton and at the same time use Spring or Ehcache or the like.
The fear of Singletons in my opinion stems from the many poor implementations that are possible, and abundant. And even if the Singleton implementation itself is 'safe', calling it directly (via static access) throughout the application leads to tight coupling and poor testability.
An improvement you can make if you have a Singleton factory in your application, is to refactor its clients so that they don't call the factory whenever they need a dependency, but provide a private field and a public setter allowing the dependency to be injected. You can then centralize the initialization of the clients, maybe in the same factory, and leave the client code clean, loosely coupled and testable (you can inject mock dependencies now). This could also be a first step towards introducing a dependency injection framework like Spring.
I hope somewhere in this rather long and rambling post I helped answer your question! (-;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With