How does one implement multiton pattern using Spring Framework's facilities?
https://en.wikipedia.org/wiki/Multiton_pattern
I want to write a factory which takes a pair of client and supplier as arguments. The factory should always return a bean of type T. For a given pair of client and supplier, the instance of T return should be a singleton, but for a different pair of client and supplier, it will be a different instance of T. Please suggest a way to implement this without implementing boilerplate code that Spring may already provide.
Interface ClientSdk {
sendRequestToClient();
}
class ClientASdk implements ClientSdk {
}
class ClientBSdk implements ClientSdk {
}
enum Client {
ClientA,
ClientB;
}
enum Supplier {
SupplierA,
SupplierB;
}
class ClientSupplier {
private Client client;
private Supplier supplier;
}
class SdkFactory {
public ClientSdk getClientSdk(ClientSupplier clientSupplier) {
//For a given ClientSupplier, always return the same
//ClientSupplier instance
}
}
@Service
class ClientRequestService {
public sendRequestToClient(ClientSupplier clientSupplier) {
ClientSdk clientSdk = SdkFactory.getSdk(clientSupplier);
clientSdk.sendRequestToClient();
}
}
Here's a solution to your problem. It does make
SdkFactorya bean as @crizzis suggests, but it also creates bean instances for eachClientSdkinstance so that each of them can be autowired or otherwise helped out by Spring. Note that I added anident()method to theClientSdkinterface just to show that theMyClientSdkbeans have in fact been autowired with the SpringEnvironment:Result:
Note that per the output, each of
client1's andclient2's ClientSdk objects are only created once, even though they're used multiple times. Also notice that since the call toident()insendRequestToClientprints the value of a property obtained by an autowiredEnvironmentinstance, autowiring of eachClientSdkobject has worked.I do realize that I used a
Stringinstead of aClientSupplierobject as the identifying key for each ClientSdk object. I did that just to keep the example as simple as I could. I expect you can expand the example to replace theclientSupplierStringwith an instance ofClientSupplierand somehow use that object as the key/identifier to insure that just oneClientSdkinstance is created perClientSupplier. That detail isn't really germain to the basic idea here.Also, please note that the question itself changed while I was working on my implementation. Given that there are now exactly two subclasses of ClientSdk, you could simply make those regular
@ComponentSpring beans. Having a small static number of those makes this problem less interesting. The technique I demonstrate here allows for an unlimited number of bean instances ofClientSdkclass without having to define a unique class for each of them. This requires that Spring create arbitrary instances of them based on runtime information. This was what the original form of the question seemed to be asking for.