Назад к вопросам
Middle
106
questionbank

Как создать singleton-бин при запуске Spring приложения?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

По умолчанию, singleton-бины в Spring создаются при первом обращении к ним (lazy loading). Чтобы создать singleton-бин при запуске приложения (eager loading), можно использовать следующие подходы:

  1. Использовать @Lazy(false) аннотацию:

    // Класс бина
    @Component
    @Lazy(false) // Указываем, что бин НЕ lazy, т.е. создается при старте контекста
    public class EagerSingletonBean {
        // ... реализация бина
    }
    

    Это наиболее явный способ указать, что конкретный бин должен быть инициализирован при старте Spring контекста. @Lazy(false) на уровне класса бина переопределяет любое глобальное или дефолтное поведение lazy loading.

  2. Конфигурация через XML:

    В XML-конфигурации Spring можно явно указать lazy-init="false" для определения бина:

    <bean id="eagerSingletonBean" class="com.example.EagerSingletonBean" lazy-init="false"/>
    

    Этот атрибут управляет политикой инициализации для данного конкретного бина.

  3. Конфигурация через Java Code (с @Bean):

    При использовании конфигурации на основе Java-кода с @Configuration и @Bean, по умолчанию бины создаются при старте контекста. Однако, если вы включили глобальное lazy loading, можно переопределить его для конкретного бина:

    // Класс конфигурации
    @Configuration
    public class AppConfig {
    
        @Bean
        @Lazy(false) // Указываем, что этот бин не lazy
        public EagerSingletonBean eagerSingletonBean() {
            return new EagerSingletonBean();
        }
    }
    

    Использование @Lazy(false) на методе с @Bean аналогично использованию ее на уровне класса с @Component.

  4. Глобальное отключение Lazy Loading:

    Можно отключить lazy loading глобально для всего приложения. Это не самый рекомендуемый подход, так как может увеличить время старта приложения, но он существует:

    • Через application.properties или application.yml:

      spring.main.lazy-initialization=false
      
    • Через Java Code:

      Можно настроить SpringApplicationBuilder:

      // В главном классе приложения
      public static void main(String[] args) {
          new SpringApplicationBuilder(YourApplication.class)
              .lazyInitialization(false)
              .run(args);
      }
      

По умолчанию Spring Boot приложения с Spring Data JPA будут создавать бины репозиториев при старте. Зависимости между бинами также влияют на порядок их создания; бин, от которого зависят другие бины, обычно создается раньше.

Выбор способа зависит от контекста и предпочтений: @Lazy(false) на уровне бина наиболее гранулированный и явный, а глобальное отключение влияет на все бины.