Один и тот же интерфейс из нескольких типов - PullRequest
0 голосов
/ 31 декабря 2018

У меня есть интерфейс, и для этого есть несколько реализаций.Каждая реализация относится к какому-либо типу.Я хочу, чтобы, когда я использую autowired, я мог получить всю реализацию определенного типа.Как я могу это сделать?

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){}

}

Я хочу получить только impl1OfType1 и impl2OfType1.И не все реализации.А в другом месте хочу получить только impl1OfType2 и impl2OfType2.

более конкретный пример -

    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){}

    }

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

Если вы исправите свой код с помощью вышеприведенных комментариев, и я понимаю вашу проблему, я предполагаю, что это может быть способом решения вашей проблемы.

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){}
}

Дайте мне знать, если я ответил на ваш вопрос.

0 голосов
/ 31 декабря 2018

Решение будет использовать @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);
    }
}

Я немного изменил имена, чтобы придерживаться соглашения Java.Они все еще немного неуклюжи и лишены контекста.

ОБНОВЛЕНИЕ

Вы можете использовать дженерики, Spring хорошо с ними справляется.Например, он будет вставлять только DogCreator и CatCreator в 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) { }
}

ОБНОВЛЕНИЕ 2

Вы могли бы написать интерфейсы маркеров, которые разбили бы существующие реализации на логическиегруппы.

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);
    }

}
...