Каков жизненный цикл Spring Bean и порядок инициализации контекста
Что проверяют
Знаете ли вы порядок этапов и понимаете ли, на каком шаге появляются прокси.
Как отвечать
Сначала контекст читает определения бинов: сканирование пакетов, классы конфигурации, автоконфигурация. На этом этапе объектов ещё нет, есть только описания.
Затем отрабатывают постпроцессоры фабрики: они правят сами определения, а не объекты. Классический пример это подстановка значений свойств.
Дальше для каждого бина по порядку:
- создание экземпляра через конструктор;
- внедрение зависимостей в поля и сеттеры;
- интерфейсы осведомлённости: бину сообщают его имя, фабрику, контекст;
- постпроцессор бина, метод до инициализации. Внутри него срабатывает аннотация выполнения после создания;
- метод интерфейса инициализации;
- метод инициализации, указанный в объявлении;
- постпроцессор бина, метод после инициализации. Именно здесь создаются прокси: обёртки для транзакций, кэширования, асинхронности и аспектов вообще.
Последний пункт объясняет главную практическую особенность: раз поведение добавляет обёртка, вызов метода изнутри того же объекта её не проходит, и аннотации молча не работают.
При закрытии контекста порядок обратный: аннотация уничтожения, метод интерфейса уничтожения, указанный метод завершения. Важная оговорка: бины с областью прототипа контейнер не уничтожает, за их закрытием следит вызывающий код.
Что ещё стоит назвать:
- ленивая инициализация откладывает создание до первого обращения, а по умолчанию синглтоны создаются при старте. Именно поэтому ошибка конфигурации обнаруживается при запуске, а не в проде;
- порядок создания определяется зависимостями, а явно управляется отдельной аннотацией;
- события контекста: можно подписаться на готовность приложения и выполнить действия после полного старта.
Где спотыкаются
Не знают, что прокси создаются на последнем шаге, и не понимают проблему самовызова.
Обращаются в конструкторе к тому, что ещё не внедрено.
Рассчитывают, что контейнер закроет бины с областью прототипа.
Делают тяжёлую работу в инициализации и получают долгий старт.