Reputation: 61
I have an interface, and there are some implementations for this. Each implementation belongs to some type. I want that when I'm using autowired I would able to get all the implementation of the certain type. How can I do it?
public interface someInterface{}
public class impl1OfType1 implements someInterface{}
public class impl2OfType1 implements someInterface{}
public class impl1OfType2 implements someInterface{}
public class impl2OfType2 implements someInterface{}
public class someClass{
@autowired
public someClass(List<someInterface> interfaceList){}
}
I want to get only impl1OfType1
and impl2OfType1
. And not all the implementation.
And at other place I want to get only impl1OfType2
and impl2OfType2
.
more concrete example -
public interface EntityCreator{
createEntity();
}
@Component
public class DogCreator implements entityCreator{}
@Component
public class CatCreator implements entityCreator{}
@Component
public class CarCreator implements entityCreator{}
@Component
public class TruckCreator implements entityCreator{}
@Component
public class AnimalsFactory{
@Autowired
public AnimalsFactory(List<EntityCreator> creators){}
}
Upvotes: 1
Views: 72
Reputation: 49656
The solution would be using @Qualifier
.
@Component
@Qualifier("place1")
class Impl1OfType2 implements SomeInterface {}
@Component
@Qualifier("place1")
class Impl2OfType2 implements SomeInterface {}
@Service
class SomeClass {
@Autowired
public SomeClass(@Qualifier("place1") List<SomeInterface> interfaceList) {
System.out.println(interfaceList);
}
}
I slightly changed the names to adhere to the Java convention. They are still a bit awkward and contextless.
You might use generics, Spring is good at dealing with them. For instance, it will inject only DogCreator
and CatCreator
into a List<EntityCreator<Animal>>
.
interface Animal {}
interface Machine {}
interface EntityCreator<T> {}
@Component
class DogCreator implements EntityCreator<Animal> {}
@Component
class CatCreator implements EntityCreator<Animal> {}
@Component
class CarCreator implements EntityCreator<Machine> {}
@Component
class TruckCreator implements EntityCreator<Machine> {}
@Component
class AnimalsFactory {
@Autowired
public AnimalsFactory(List<EntityCreator<Animal>> creators) { }
}
You could write marker interfaces which would break down existing implementations into logical groups.
interface AnimalCreator {}
interface EntityCreator<T> {}
@Component
class DogCreator implements EntityCreator, AnimalCreator {}
@Component
class CatCreator implements EntityCreator, AnimalCreator {}
@Component
class AnimalsFactory {
@Autowired
public AnimalsFactory(List<AnimalCreator> creators) {
System.out.println(creators);
}
}
Upvotes: 1
Reputation: 560
If you correct your code with above comments and I understand your problem, I assume this can be a way to solve your issue.
public interface Someinterface<T extends someType> {}
public class someType{}
public class Type1 extends someType{}
public class Type2 extends someType{}
public class TypedInterface1 implements Someinterface<Type1> {}
public class TypedInterface2 implements Someinterface<Type2> {}
public class someClass{
@Autowired
public someClass(List<TypedInterface1> interfaceList){}
}
Let me know if I answered your question.
Upvotes: 0