@Autowire an Interface as Map<String, InterfaceName> is possible?

Viewed 318

Let's say I have a "SomeInterface" and I have two springComponentImpl that implements that "SomeInterface".

I know I can autowire both implementations, together at once, with:

@Autowire
private List<SomeInterface> springComponentsImplList;

Could I inject them in a way like this?:

@Autowire
private Map<String,SomeInterface> springComponentsImplList;

So that way I could get the implementation by a "key"? It would be perfect if that key is the class name or something and generated automaticaly.

Thanks!

2 Answers

The following should work out-of-the-box, where the map contains the bean names as keys and the corresponding bean instances as values:

@Autowired
private Map<String, Foo> allBeansOfType;

But you may also try to get all bean instances of a particular type along with their names using ListableBeanFactory:

private Map<String, Foo> allBeansOfType;

@Autowired
public MyClass(ListableBeanFactory beanFactory) {
    this.allBeansOfType = beanFactory.getBeansOfType(Foo.class);
}

You can inject the spring beans into two separate List

First approach : If you have only each of them, then name them differently and use @Qualifier

Service Interface

public interface ServiceInterf {

}

ImplementOne

@Service("implementOne")
public class ImplementOne implements ServiceInterf {

}

ImplementTwo

@Service("implementTwo")
public class ImplementTwo implements ServiceInterf {

}

And you can use @Qualifier

@Autowired
@Qualifier("implementOne")
private List<ServiceInterf> implementOne;

@Autowired
@Qualifier("implementTwo")
private List<ServiceInterf> implementTwo;

Second approach : If you have multiple of them, then you can declare them in config class using @Qualifier 5.2. Using @Qualifier to Select Beans

@Bean
@Qualifier("implementOne")
public ServiceInterf getServiceInterf1() {
    return new ImplementOne();
}

@Bean
@Qualifier("implementOne")
public ServiceInterf getServiceInterf2() {
    return new ImplementOne();
}

@Bean
@Qualifier("implementTwo")
public ServiceInterf getServiceInterf3() {
    return new ImplementTwo();
}

@Bean
@Qualifier("implementTwo")
public ServiceInterf getServiceInterf4() {
    return new ImplementTwo();
}

And also if you want to do them into Map use constructor injection

private Map<String, List<ServiceInterf>> mapOfLists;

@Autowired
public TestMap(@Qualifier("implementOne") List<ServiceInterf> implementOne, 
               @Qualifier("implementTwo") List<ServiceInterf> implementTwo) {
    mapOfLists = Map.of("implementOne",implementOne,"implementTwo",implementTwo);  
    // Map.of is from java 9 

}
Related