Создание бобов Spring по требованию, а не при запуске - PullRequest
0 голосов
/ 10 октября 2019

Spring Boot 2.x здесь. В настоящее время у меня есть куча bean-компонентов, определенных внутри класса @Configuration, например:

@Configuration
public class SomeConfig {

    @Bean
    public Fizz fizz() { ... }

    @Bean
    public Buzz buzz() { ... }

}

Обычно Spring запускает этот класс и создает экземпляры этих bean-компонентов при startup . Однако в моем случае я хочу, чтобы Spring пропустил , загружая этот класс (и создавая его компоненты) при запуске, и вместо этого делал это программно / по требованию, что-то вроде этого:

public void processRequest(SomeRequest request) {

    Fizz fizz = SpringAdhocLoader.load(SomeConfig.class, Fizz.class);
    Buzz buzz = SpringAdhocLoader.load(SomeConfig.class, Buzz.class);

    // use these two beans in this method somehow

}

Есть очень конкретная причина, почему я должен сделать это, которая выходит за рамки этого вопроса. Поэтому я бы действительно оценил бы ответ: " Да, вы можете это сделать, и вот как ... " или " Нет, этого нельзя сделать с помощью Spring ивот почему ...", вместо ответов / комментариев, спрашивающих меня почему Я хочу это сделать. Поверьте мне, мне нужно!

В конце дня я ищу способ сказать Spring не , чтобы создать экземпляр всех бинов в моем классе SomeConfig до другогочасть моего кода специально хочет, чтобы они были созданы. Возможно ли это, и если да, то как?


Обновление

Что если Fizz выглядит следующим образом:

@Component
public class Foobar {
    ...
}

public class Fizz {

    @Autowired
    private Foobar foobar;

    ...
}

Будет аннотация @Lazyна SomeConfig все еще предотвращать создание экземпляра Fizz, даже если он автоматически подключен / введен с зависимостью @Component?

1 Ответ

1 голос
/ 10 октября 2019

В зависимости от ваших точных требований, есть несколько способов сделать это:

  • Используйте @Lazy, если все должны использовать один и тот же экземпляр объекта, обратные вызовы уничтожения будут вызываться автоматически, иобъект, созданный при первом запросе bean-компонента.

  • Используйте более короткий @Scope, такой как "сеанс" или "запрос", если каждый в этой области должен использовать один и тот же экземпляр объекта, обратные вызовы уничтожения будут вызываться автоматически, и объект будет создан при первом запросе.

  • Используйте @Scope("prototype"), если каждый должен получить новый экземпляр объекта, и вы готовы вызвать любойобратные вызовы уничтожения вручную.

Во всех случаях внедрение «голого» бина потребует создания этого бина. Вы можете избежать этого, введя Provider вместо:

class Foo {
    @Inject Bar bar;  // requests the creation of bar
}

class Foo {
    @Inject Provider<Bar> barProvider; // does not cause the creation of bar

    void something() {
        Bar bar = barProvider.get(); // requests the creation of bar 
    }
}
...