Бины в Spring инициализируются контейнером IoC (Inversion of Control), чаще всего ApplicationContext. Происходит это следующим образом:
- Сканирование и определение бинов: Контейнер сканирует классы (на основе конфигурации: XML, JavaConfig, аннотации), находит определения бинов и регистрирует их в реестре.
- Создание экземпляров: Контейнер создает экземпляры бинов. По умолчанию используются конструкторы без параметров, но могут использоваться и другие конструкторы, определенные в конфигурации или с помощью
@Autowired.
- Внедрение зависимостей (Dependency Injection): После создания экземпляра контейнер внедряет зависимости (другие бины) в созданный бин. Это может происходить через:
- Конструкторы (
@Autowired на конструкторе).
- Сеттеры (
@Autowired на сеттере).
- Поля (
@Autowired на поле).
- Вызов методов инициализации: Если у бина определены методы инициализации (например, помеченные
@PostConstruct, определенные в XML как init-method, или реализующие интерфейс InitializingBean), контейнер вызывает их после внедрения зависимостей.
- Готовность к использованию: После всех этих шагов бин считается полностью инициализированным и готовым к использованию.
Жизненный цикл бина в 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)
Пример с аннотациями:
java