How do I instantiate a Spring Bean that has some @Autowired
beans within it? The caveat is that the instance bean type must be discovered dynamically at runtime (whereas the @Autowired
bean can still be singleton).
Example:
Interface
public interface Client {
public void process(String s);
}
ClientA.class
@Component
@Scope("prototype")
public class ClientA implements Client {
@Autowired
MyHelperService svc;
public void process(String s) {...}
}
ClientB.class
@Component
@Scope("prototype")
public class ClientB implements Client {
@Autowired
MyHelperService svc;
public void process(String s) {...}
}
ClientFactory.class
@Component
public class ClientFactory {
public Client createClient(String type) {
.. create an instance of ClientA or ClientB ..
}
}
MyService.class
@Service
public class MyService {
@Autowired
ClientFactory factory;
Client client;
public void processList(List<String> requests) {
for(String s: requests) {
client = factory.createClient(s);
client.process(s);
}
}
}
Though this sample code is for illustration purposes here, the pattern applies to our needs. More specifically, we are multi-threading our app by creating Callable<?>
tasks and submitting them to an ExecutorService
with parallel threads (and it's those tasks which each need their own instance of Client
whose lifespan should end after we call it's process
method).
The client instances use a singleton shared MyHelperService
service. Since that should be @Autowired
, our factory can't simply construct the clients like new ClientA()
or new ClientB()
.