Reputation: 2459
I have three main classes: Controller, Service1, Service2
Controller: Simple controller that retrieves input (list) and passes it to Service1
Service1: Receives input from controller procceses and passes it to Service2
Service2: Receives processed input from Service 1 and sends a POST request to an external service
These three are all annotated with @Component and based from what I was reading, Spring beans, by default, are singletons unless specified to be prototype which creates a new instance every time the bean is utilized. It is important to note that these are all stateless.
The main flow works like this:
Controller -> Service 1 -> Service 2.
It's simple as is and works well synchronously. But I want asynchronous, fire and forget, behavior for these three classes.
My main concern is that Service1 can be a possible bottleneck since it's doing a lot of processing that takes (4-5 seconds). I mean, sure, the controller can spawn a lot of CompleteableFutures but since Service1 is a singleton, a single thread locks the whole method until it finishes which results to somewhat synchronous behavior.
My question is would setting the scope to 'prototype' for Service1 solve this issue?
Upvotes: 0
Views: 298
Reputation: 691635
since Service1 is a singleton, a single thread locks the whole method until it finishes
No, not at all. That would only be true if the method was synchronized. But there's no reason to make it synchronized, since the object is stateless. Several threads execute the methods of a given object concurrently. That's the whole point of threads.
Note that
prototype which creates a new instance every time the bean is utilized
is also wrong. A new instance is created every time a bean is requested to the application context. So if you have two controllers both using a prototype bean Foo, bith will have their own instance of Foo. But there will only be 2 instances, used and shared by all threads executing the methods of Foo. Read the documentation, which explains it.
If you really want your controller to send back the response before the processing is finished, then use Async, as described in the documentation.
Upvotes: 1