I've been spending the last x number of hours trying to rack my head around the argument for using/not using singleton objects in servlets. I've seen many articles and posts describing the many disadvantages of singletons .... hard to test, hides dependencies etc..etc.. but I have a real world example where I cannot see a more efficient way than to create a singleton...
We have an application (using struts x1) that externally authenticates tokens entered by the user by calling another servlet and passing some additional parameters. The flow works as follows:
During the servlet initialisation, a ServletContextAttributeListener is called that creates a new (singleton) instance of a validator method and sets it to the servlet context:
The constructor of this object then does some initialisation by setting some class static variables that will be used during the authentication process.
On each page request where validation is required, the singleton instance is retrieved from the servlet context and used to validate the user entry i.e.
Validator validator = Validator.getInstance();
Boolean validated = validator.validate("user entry params"); - uses static params set in init method
This method ensures that each request always uses the same instance of the Validator that has been created during the servlet start-up.
In terms of the arguments I have read against singleton....
- Hard to test? I'm not sure this would be the case in this scenario, nothing is required to be DI'ed.
- hides dependency - As there are no other objects that depend / rely / are referenced by this object, I can't see this being a problem
- the singleton can be reference globally...correct but I'm getting from the servlet context, not using its global accessor (is this any better?)
Am I missing something here.... Is this bad practice? I can't see how implementing a factory would be any different in this scenario? The factory class itself would be a singleton in exactly the same way as the class it creates?
Would appreciate if someone could clarify this for me, I might be way off the mark here....
I think the real problem with Singletons is they get misused. It looks like you've thoroughly looked at your options, weighed the pros & cons, and have decided Singletons look like the best solution.
The one thing you might want to consider is to create an Interface that your Singleton implements, and then have your servlets use the Interface. This is what I typically do if I need a Singleton object in my servlets. Either have a context listener or initializer servlet implement the Interface, and store it as a context attribute for other servlets & jsps. Although I have never had it come up, I could change out my Singleton object with another of the same Interface merely by changing my context listener or initializer servlet.
In preparing for battle I have always found that plans are useless, but planning is indispensable. -- Dwight D. Eisenhower