Всегда ли выполняется метод @PostConstruct у Spring-бина со scope Singleton?

«Всегда ли выполняется метод @PostConstruct у Spring-бина со scope Singleton?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, метод @PostConstruct у singleton-бина выполняется ровно один раз, но при соблюдении следующих условий:

  • Контекст Spring успешно создан и запущен.
  • Бин успешно инстанциирован (нет неразрешимых зависимостей или исключений в конструкторе).
  • Контекст не был закрыт до момента обращения к бину (для ленивых бинов).

Ключевые моменты:

  • Для eager-бинов (по умолчанию): Метод выполняется во время инициализации контекста.
  • Для lazy-бинов (@Lazy): Метод выполняется при первом запросе бина из контекста.
  • Порядок: На порядок выполнения может влиять аннотация @DependsOn.

Пример и исключения:

@Component // Singleton scope по умолчанию
public class ServiceBean {
    @PostConstruct
    public void init() {
        System.out.println("PostConstruct executed for singleton bean.");
    }
}

Когда @PostConstruct НЕ выполнится:

  1. Если бин создан вручную через new ServiceBean() (вне управления Spring).
  2. Если в методе @PostConstruct или на предыдущих этапах жизненного цикла (например, в конструкторе) возникло необработанное исключение.
  3. Если контекст Spring был уничтожен (context.close()) до инициализации lazy-бина.