Spring Boot - интерфейс Autowiring, реализованный различными компонентами - PullRequest
0 голосов
/ 23 января 2020

У меня есть несколько bean-компонентов с @Component, реализующими обобщенный c интерфейс.

У меня есть класс, в котором я использую методы из этих bean-компонентов. Вместо автоматической разводки каждого компонента по отдельности, я рассчитывал на автоматическую разводку интерфейса в виде списка.

Но как мне вызывать методы разных компонентов, когда я просто подключаю интерфейс?

public interface Generic {
}

@Component
public class A implements Generic{
.....
public void test{
}

}

@Component
public class B implements Generic{
.....
public void read{}

}


@component class C {

@Autowired
List <Generic> mylist;  // type of list is Generic

Теперь мне нужно получить доступ к чтению из B и проверить из A

Ответы [ 3 ]

1 голос
/ 23 января 2020

С новым вопросом вы МОЖЕТЕ сделать это так, но Я думаю, что лучше использовать 2 отдельных списка вместо instanceOf.

public interface Generic { }

public interface GenericTestable extends Generic { 
    void test()
}

public interface GenericReader extends Generic { 
    void read()
}

@Component
public class A implements GenericTestable { 
   public void test() { }
}

@Component
public class B implements GenericReader { 
   public void read() { } 
}

@Component
public class C {

   private final List<Generic> genericItems;

   @Autowired
   public C(List<Generic> genericItems) {
       this.genericItems = genericItems;
   }

   public void callThem() {
       this.genericItems.forEach(this::callMethodOnSpecificType);
   }

   private void callMethodOnSpecificType(Generic genericItem) {
       if (genericItem instanceof GenericTestable) {
           ((GenericTestable) genericItem).test();
       } else if (genericItem instanceof GenericReader) {
           ((GenericReader) genericItem).read();
       }
   }
}

Но я думаю, что что-то вроде этого - лучший подход. Более чистый и быстрый код. Удалите интерфейс Generi c и используйте только 2 отдельных интерфейса.

public class BetterC {

    private final List<GenericTestable> genericTestables;
    private final List<GenericReader> genericReaders;

    @Autowired
    public BetterC(List<GenericTestable> genericTestables, List<GenericReader> genericReaders) {
        this.genericTestables = genericTestables;
        this.genericReaders = genericReaders;
    }

    public void callTestables() {
        this.genericTestables.forEach(GenericTestable::test);
    }

    public void callReaders() {
        this.genericReaders.forEach(GenericReader::read);
    }
}
0 голосов
/ 23 января 2020

Как насчет использования интерфейса Generi c для маршрутизации вызова?

Из java -do c api: Заказано

Ordered - это интерфейс, который может быть реализован объектами, которые должны быть заказаны, например, в Collection. Фактический порядок можно интерпретировать как расстановку приоритетов, при этом первый объект (с наименьшим значением порядка) имеет наивысший приоритет.

import org.springframework.core.Ordered;

public interface Generic extends Ordered {
    void call();
}
----
@Component
public class A implements Generic {

    @Override
    public int getOrder() {
        return 2;
    }

    @Override
    public void call() {
        test();
    }

    public void test() {
        System.out.println("Call test()");
    }
}
----
@Component
public class B implements Generic {

    @Override
    public int getOrder() {
        return 1;
    }

    @Override
    public void call() {
        read();
    }

    public void read() {
        System.out.println("call read()");
    }
}
----
@Component
public class C {

    List<Generic> list;

    public C(List<Generic> list) {
        this.list = list;
    }

    public void testMethod() {
        for(Generic g: list) {
            g.call();
        }
    }
}
0 голосов
/ 23 января 2020

попробуйте это в вашей реализации

@Component
@Qualifer("a")
public class A implements Generic{ ..... public void test(){ }}

@Component
@Qualifer("b")
public class B implements Generic{ ..... public void read(){ }}

@component 
public class C {

    @Autowired
    Generic a;

    @Autowired
    Generic b;

    ... call respective methods

}
...