Issue
I have a ReservationController in my spring project that injects ReservationService. Here is my ReservationController Class
I have two implementations of ReservationService: ReservationServiceImpl and ReservationDoublePriceServiceImpl. Here is my ReservationService1 Class
Here is my ReservationService2 Class
I want ReservationController to choose service's implementation depended on authenticated user's authority(If authority is User choose ReservationServiceImpl and if authority is DoublePriceUser choose ReservationDoublePriceServiceImpl).
Can someone suggest how can I do this?
P.S I have done with application.properties parameter and qualifiers, but it only makes me an opportunity to choose only one of my service implementations.
How can I choose service beans in Runtime?
Solution
There are plenty ways to do that, I'd suggest to start with something simple. Add a supports(Set<String> authorities)
method in your ReservationService
interface, and the implementation itself will tell if it supports the authorities passed (check if contains the role).
Create a Factory class, which will be used to choose the right implementation for you, like so:
@Component
public class ReservationServiceFactory {
private final List<ReservationService> services;
public ReservationService getService(Set<String> authorities) {
for (ReservationService service : this.services) {
if (service.supports(authorities)) {
return service;
}
}
throw new IllegalArgumentException("Could not resolve ReservationService for authorities " + authorities);
}
}
public interface ReservationService {
// add this method in your ReservationService interface
boolean supports(Set<String> authorities);
}
And, in your controller you can do something like:
@GetMapping
public void anyMethod(/*inject the authentication object*/Authentication authentication) {
this.reservationServiceFactory.getService(authentication.getAuthorities()).doSomething();
}
Answered By - Marcus Hert da Coregio
Answer Checked By - David Marino (JavaFixing Volunteer)