Reading form this http://docs.grails.org/3.3.10/ref/Services/scope.html
and By default services are "singleton",
So Does Grails automatically lock/Synchronize the service object if the scope is a singleton?
in case many requests using the same service a
Please advise
By default services are "singleton",
So Does Grails automatically lock/Synchronize the service object if
the scope is a singleton?
No. Grails configures Spring to create a single instance of your service and inject that instance everywhere it needs to be injected. In general services don't need to be synchronized if they are stateless but if you are doing something that calls for synchronization, do that.
Related
Imagine you inject a single database connection to a handful of service classes. They now share what's essentially a global mutable state. How do DI frameworks deal with this? Do they:
Freeze the dependency before injection?
Only share immutable objects?
Wrap each dependency in a decorator to only provide exactly what's dependent on?
I tried searching for this and am a bit surprised I didn't find much. Feel free to provide links.
Related: https://en.wikipedia.org/wiki/Principle_of_least_privilege
Most DI containers provide the feature of registering a dependency within a Lifetime. For instance in .net core DI you can register a service with three different lifetimes:
Singleton: There is only one single instance. All the consumers of that service will use that instance. If one consumer changes the state of that dependency, all the other consumers will see that change.
Scoped: There is one instance per scope, where a scope is a web request. If a consumer changes the state of a scoped service, all the other consumers that will run in the same web request will see the change.
Transient: Each consumer uses a different instance of the service.
Always in .net core, the DBContext is (by default) added as a scoped service, this means that in the same web request all the consumers will use the same instance and this is useful when you need to run a transaction across different consumers (or better across different repositories).
I have an authentication_service, which is required in all the services throughout the application. So, I don't want to inject this service every time (DRY). Is there a way, I can have this common service accessible from all the modules, with injecting via factory?
Thanks!!
You can use service initializers, great article with examples and more important with explained consequences:
http://www.masterzendframework.com/zend-framework/easy-setter-injection-in-zend-framework-2
I suggest you create a base service which defines all the common service requirements, such as your $authService property and the constructor that sets it. Then have your services extend that. Avoid reimplementing the constructor and property in every service to stay DRY, but injecting it via every service's factory is expected.
When injecting a stateful session bean inside a stateless session bean using DI, what happens exactly:
Did the container inject a new instance of stateful bean for every stateless bean (which exists in a pool), or it is the same instance shared between them?
Why it is indicated that using JNDI in this case is better than DI?
I really didn't get that.
Basically it doesn't make sense to inject stateful into stateless, because that stateful will be shared by many clients, if they happen to get same stateless instance, or one client can also access different stateful instances, if it access different stateless instances.
Using JNDI or not, doesn't make any difference in this case. Stateful cannot be shared by many clients and each statelss instance is a different client. If you will use JNDI then depending where you do the lookup you can end up with new stateful instance with every call to the stateless.
Any reason why would you like to inject stateful in stateless?
For each session the #Statefull will be new instance.
#Statefull isn't a direct instance, it's a proxy and can be changed every time when is needed even inside #Stateless
What actually happens when we do def someService? Does the service code get linked to the controller code?
Grails uses spring IOC, your controllers and services are managed as spring beans, when you define a service inside a controller, spring will inject the service inside the controller, code does not get linked in anyway, just reference to service will be set. Though its not a much expensive operation, you would not want to define service dependencies that are not used to keep the code clean
I think under the hood it's the same process as Spring's #Autowired annotation, so you pay a bit of a performance penalty on start up but I don't think it's significant.
There's another stackoverflow question on the subject here.
Does the service code get linked to the controller code?
That does not make sense.
Actually services in grails are singleton by default.So if you inject a Service by def serviceName it wont create a new service object but a reference to same old service object.
So its not expensive of course.
But if in a service there is a property static session="prototype" or some non-singleton like this.Then it is expensive .
My controllers now implement an interface and inject a repository implementation using the Unity framework. My question is, are these injected implementations singletons? Does that mean all of my users hitting the repository (from the controller) use the same instance?
It depends on whether you carry some ORM session along with your repository instance. If your repository is just a bunch of static methods than you shouldn't care and you can make it a singleton. Otherwise you want to preserve the state only within one web request so that other requests threads don't interfere with it.
Unity, unlike other IoC frameworks. doesn't come with singleton per web request lifetime manager, but you can easily implement it, see here for instance:
Singleton Per Call Context (Web Request) in Unity
No, do not make repositories singleton, special in a web application.
The controller factory create the repository (using Unity) and inject them in the controller.
Taken from the MSDN Unity docs...
The lifetime of the object it builds will correspond to the lifetime you specify in the parameters of the method. If you do not specify a value for the lifetime, the type is registered for a transient lifetime, which means that a new instance will be created on each call to Resolve...
Include an instance of the ContainerControlledLifetimeManager class in the parameters to the RegisterType method to instruct the container to register a singleton mapping.
So basically, the injection is transient unless you specify it as a singleton.