Reputation: 563
I have various protocols that my system is using. I mark an interface and provide appropriate implementations. For example SSHprotocol
and HttpProtocol
both implements Protocol
. There may be multiple which I add in the future. Now I have a class as follows:-
class Test {
@Autowired
private Protocol protocol;
public void getProtocol(String name) {
return protocol;
}
}
The getProtocol
should return a Protocol
object based on the Protocol
name. In short I want Spring to Autowire the specific bean based on name parameter.
Does spring support this? I can have multiple @Autowired
with corresponding Qualifiers. But that may make me to write 10-15 variables with corresponding Autowiring annotations. But that is too much of code making it difficult to manage. Factory may be an alternative but how will that solve my problem?
Upvotes: 2
Views: 2550
Reputation: 22271
You're misunderstanding the @Autowired
concept. The wiring, assigning the object, is done once, just after the creation of the object.
edit: dunni's answer is definitely better, unless maybe you want to create a whitelist of protocols
You could @Autowired
all protocols and case
them:
class Test {
@Autowired
private Protocol httpProtocol;
@Autowired
private Protocol sshProtocol;
public void getProtocol(String name) {
switch(name.toLowerCase()) {
case "ssh": return sshProtocol;
case "http": return httpProtocol;
}
throw new YourException("unknown protocol "+name);
}
}
You would have to, of course, have all the Protocol
implementation registered as beans with appropriate names. You could do it like that:
@Configuration
class ProtocolConfiguration {
@Bean
public Protocol httpProtocol() {
return new HttpProtocol();
}
@Bean
public Protocol sshProtocol() {
return new SSHProtocol();
}
}
Upvotes: 1
Reputation: 44545
You can autowire a field of a map type, like that:
@Autowired
private Map<String, Protocol> protocols;
Spring will then populate the map with the bean name as key and the bean instance as value. So in your getProtocol method you could just do
public void getProtocol(String name) {
return protocols.get(name);
}
You can adjust the bean name of your beans by specifying the value on the component annotation:
@Component("http")
public class HttpProtocol ...
Upvotes: 6