Несколько компонентов Spring \ Beans одного типа - PullRequest
0 голосов
/ 17 декабря 2018

У меня есть базовый класс Foo и несколько классов, которые наследуют его.

До сих пор мне требовался ровно один из каждого

Так что я просто сделал:

@Autowired 
private List<Foo> foos;

Но все изменилось, и я хотел бы создать несколько объектов каждого типа (например, x экземпляров для Foo1, y экземпляров для Foo2 и т. Д.)

Как можноЯ делаю это с помощью Spring Boot?

Примечание: мне не нужно, чтобы он был заполнен в списке.

РЕДАКТИРОВАТЬ:

Iобъясню подробнее о проблеме, с которой я сталкиваюсь.Каждый класс представляет тип задачи (это Runnable).Каждое задание имеет фиксированное количество потоков.Я хотел бы создать новый объект для каждого потока.

Итак, мой вопрос: как использовать Spring для этой цели?Назад, когда мне нужно было только один экземпляр для каждой задачи, это было легко (см. Пример List<Foo>)

Ответы [ 2 ]

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

TL; DR;

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

В нем используется фабрика, которая содержит все зависимости Foo и мы делаем Foo больше не бобовые.Поэтому мы не полагаемся на Spring для создания экземпляров n Foo, вместо этого мы можем программно решить, сколько мы хотим создать.

Это, конечно, имеет некоторые плюсы и минусы:

Pro:

  • Возможно программное создание n экземпляров.(может быть установлено через свойство, может быть вычислено, может быть введено ...)
  • Мы не используем пружину, чтобы решить, сколько экземпляров создается
  • (возможно больше, ноСейчас я не могу думать о большем)

Con:

  • У вас есть накладные расходы на создание нового класса (фабрики) для каждого типа, который вы хотитесоздать

Фактический ответ

1.Создайте интерфейс

. Он будет использоваться для создания n экземпляров типа:

interface Factory<T> {
    T create();
}

2.Создание реализаций

Это должно быть сделано для каждого типа, который вы хотите построить.Кроме того, каждая созданная реализация должна быть объявлена ​​как пружинный компонент:

// Our object we want to create
class Foo {
    private final Dependency1 d1;
    private final Dependency2 d2;

    public Foo(Dependency1 d1, Dependency2 d2){
        this.d1 = d1;
        this.d2 = d2;
    }

    // methods of foo
}

// our factory for the object
@Component
class FooFactory implements Factory<Foo>{
    private final Dependency1 d1;
    private final Dependency2 d2;

    @Autowired
    public FooFactory(Dependency1 d1, Dependency2 d2){
        this.d1 = d1;
        this.d2 = d2;
    }

    @Override
    public Foo create(){
        return new Foo(d1, d2);
    }
}

3.Введите фабрику

Это делается в сервисе, который мы хотим создать n экземпляров Foo:

@Service
class MyService{
    private final FooFactory fooFactory;

    @Autowired
    public MyService(FooFactory fooFactory){
        this.fooFactory = fooFactory;
    }

    public void doSomething(){
        // can of course be generated with a normal for loop too
        List<Foo> foos = IntStream.range(0, 10)
            .mapToObj(i -> fooFactory.create())
            .collect(Collectors.toList());

        // do something with 10 foo instances   
    }
}
0 голосов
/ 17 декабря 2018

Если я правильно понимаю ваш вопрос, вам нужно более одного экземпляра bean-компонента, тогда вам нужно объявить область действия этого bean-компонента в PROTOTYPE, потому что по умолчанию spring делает их SINGLETON (один bean на контейнер).Чтобы сделать ваш боб ПРОТОТИПОМ, вам просто нужно добавить эту аннотацию @Scope("prototype") в ваш класс.Вот некоторые подробности: https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s04.html

HTH

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...