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

Как инициализируются бины в Spring?

Sobes Copilot

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

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

sobes.tech AI

Бины в Spring инициализируются контейнером IoC (Inversion of Control), чаще всего ApplicationContext. Происходит это следующим образом:

  1. Сканирование и определение бинов: Контейнер сканирует классы (на основе конфигурации: XML, JavaConfig, аннотации), находит определения бинов и регистрирует их в реестре.
  2. Создание экземпляров: Контейнер создает экземпляры бинов. По умолчанию используются конструкторы без параметров, но могут использоваться и другие конструкторы, определенные в конфигурации или с помощью @Autowired.
  3. Внедрение зависимостей (Dependency Injection): После создания экземпляра контейнер внедряет зависимости (другие бины) в созданный бин. Это может происходить через:
    • Конструкторы (@Autowired на конструкторе).
    • Сеттеры (@Autowired на сеттере).
    • Поля (@Autowired на поле).
  4. Вызов методов инициализации: Если у бина определены методы инициализации (например, помеченные @PostConstruct, определенные в XML как init-method, или реализующие интерфейс InitializingBean), контейнер вызывает их после внедрения зависимостей.
  5. Готовность к использованию: После всех этих шагов бин считается полностью инициализированным и готовым к использованию.

Жизненный цикл бина в Spring выглядит так:

  • Instantiation
  • Populate Properties (DI)
  • setBeanName() (реализация BeanNameAware)
  • setBeanFactory() (реализация BeanFactoryAware)
  • setApplicationContext() (реализация ApplicationContextAware)
  • postProcessBeforeInitialization() (вызов методов BeanPostProcessor)
  • afterPropertiesSet() (реализация InitializingBean)
  • Custom init method (определенный в конфигурации или с @PostConstruct)
  • postProcessAfterInitialization() (вызов методов BeanPostProcessor)
  • Ready to use
  • Container Shutdown
  • destroy() (реализация DisposableBean)
  • Custom destroy method (определенный в конфигурации или с @PreDestroy)

Пример с аннотациями:

public class MyBean {

    private DependencyBean dependency;

    @Autowired
    public MyBean(DependencyBean dependency) { // Инyección через конструктор
        this.dependency = dependency;
        System.out.println("MyBean: Constructor called");
    }

    @PostConstruct
    public void init() { // Метод инициализации
        System.out.println("MyBean: @PostConstruct called");
    }

    public void doSomething() {
        System.out.println("MyBean: doSomething called");
        dependency.doDependencyStuff();
    }

    @PreDestroy
    public void destroy() { // Метод уничтожения
        System.out.println("MyBean: @PreDestroy called");
    }
}

public class DependencyBean {
    public void doDependencyStuff() {
        System.out.println("DependencyBean: doDependencyStuff called");
    }
}