I'm just starting out and I dont think i understand it very well. From what I understand all controllers are created as dependencies the moment the router is created. They then live on until the router dies when the application terminates. If this is the case declaring them as singletons seem redundant.
If you have a controller that is instantiated by the router (ie. the default), then they are implicitly singletons, because the router exists only once. However if you inject the controller somewhere else, you'd still get a new instance unless it is marked as singleton.
Source: https://github.com/playframework/playframework/issues/4508#issuecomment-127820190
To get rid of global state (which goes against the idea of a stateless design) Play introduced DI (I think around v2.4) and in v2.5 it now uses an injected router by default. Google Guice is the default DI framework packaged by Play (you can use others but Guice is the default).
Now (in general) Guice takes the view that creating new instances of a Controller is faster, and more thread safe than using a singleton - see the Guice docs for more.
If you have a need to restrict instances of a controller to only 1 then you can mark it a singleton BUT you have to make it Thread-safe since it will then be shared between threads.
I think the Activator templates could do with a bit more documentation around them to explain why they seem to generate @Singleton
controllers when they do not seem to be needed since it is confusing. HomeController
(in the Play-Scala seed) for example is confusingly declared @Singleton
when it exhibits no case for it.
In general, it is probably best to not use @Singleton
unless you have a fair understanding of immutability and thread-safety. If you think you have a use case for Singleton though just make sure you are protecting any shared state.
In a nutshell, don't use @Singleton
.
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