Как кастомизировать жизненный цикл бина в Spring?

«Как кастомизировать жизненный цикл бина в Spring?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, поведение бина можно кастомизировать на разных этапах его жизненного цикла. Spring предоставляет несколько механизмов, выбор которых зависит от требуемого уровня контроля.

Основные способы:

  1. Аннотации жизненного цикла (наиболее распространенный способ для кастомизации отдельного бина):

    @Component
    public class CustomBean {
        @PostConstruct
        public void init() {
            // Логика, выполняемая после инъекции зависимостей и настройки свойств.
        }
        @PreDestroy
        public void cleanup() {
            // Логика, выполняемая перед уничтожением бина (при закрытии контекста).
        }
    }
  2. Реализация интерфейсов InitializingBean и DisposableBean (менее предпочтительный из-за связывания с Spring API):

    @Component
    public class CustomBean implements InitializingBean, DisposableBean {
        @Override
        public void afterPropertiesSet() {
            // Аналог @PostConstruct. Вызывается после установки всех свойств.
        }
        @Override
        public void destroy() {
            // Аналог @PreDestroy.
        }
    }
  3. Использование BeanPostProcessor (для глобальной кастомизации всех бинов в контейнере):

    @Component
    public class CustomBeanPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) {
            // Вызывается ДО методов инициализации (@PostConstruct, afterPropertiesSet).
            // Можно модифицировать или заменить бин.
            return bean;
        }
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) {
            // Вызывается ПОСЛЕ методов инициализации.
            // Часто используется для создания прокси (например, в AOP).
            return bean;
        }
    }

Практический совет: Для кастомизации конкретного бина используйте @PostConstruct/@PreDestroy. Для применения сквозной логики ко многим бинам (например, логирование, инъекция дополнительных зависимостей) реализуйте BeanPostProcessor.