← Назад к вопросам

Какой жизненный цикл бина?

2.0 Middle🔥 211 комментариев
#Spring Boot и Spring Data#Spring Framework

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Жизненный цикл Bean в Spring

Жизненный цикл Bean в Spring контейнере — это последовательность этапов от создания до удаления объекта. Понимание этого процесса критически важно для правильного управления ресурсами и инициализацией данных в приложении.

Основные этапы жизненного цикла

Жизненный цикл Bean состоит из 7 основных этапов:

1. Instantiation (Создание экземпляра)
   ↓
2. Populate Properties (Заполнение свойств)
   ↓
3. BeanNameAware / BeanFactoryAware / ApplicationContextAware (Aware интерфейсы)
   ↓
4. BeanPostProcessor.postProcessBeforeInitialization (Pre-Init)
   ↓
5. InitializingBean.afterPropertiesSet() / @PostConstruct / init-method (Инициализация)
   ↓
6. BeanPostProcessor.postProcessAfterInitialization (Post-Init)
   ↓
7. Bean готов к использованию (Ready)
   ↓
8. Destruction (Уничтожение)

Детальное описание каждого этапа

1. Instantiation (Создание экземпляра)

Spring создаёт экземпляр bean'а, используя конструктор (с параметрами или без):

@Component
public class MyBean {
    public MyBean() {
        System.out.println("1. Constructor called - Bean instantiated");
    }
}

2. Populate Properties (Заполнение свойств)

Spring устанавливает значения зависимостей через Setter injection или Field injection:

@Component
public class MyBean {
    @Autowired
    private MyService myService;
    
    private String name;
    
    @Autowired
    public void setName(String name) {
        System.out.println("2. Setter called - Properties populated");
        this.name = name;
    }
}

3. Aware Interface (BeanNameAware, BeanFactoryAware, ApplicationContextAware)

Если bean реализует интерфейсы Aware, Spring вызовет соответствующие методы:

@Component
public class MyBean implements BeanNameAware, ApplicationContextAware {
    
    @Override
    public void setBeanName(String name) {
        System.out.println("3a. setBeanName called: " + name);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext context) {
        System.out.println("3b. setApplicationContext called");
    }
}

Другие Aware интерфейсы: BeanNameAware, BeanFactoryAware, ApplicationContextAware, EnvironmentAware, MessageSourceAware, ApplicationEventPublisherAware, EmbeddedValueResolverAware.

4. BeanPostProcessor.postProcessBeforeInitialization

Spring вызывает методы всех BeanPostProcessor для PRE-инициализации:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        System.out.println("4. postProcessBeforeInitialization for " + beanName);
        return bean;
    }
}

Примеры встроенных BeanPostProcessor:

  • AutowiredAnnotationBeanPostProcessor — обрабатывает @Autowired
  • CommonAnnotationBeanPostProcessor — обрабатывает @PostConstruct
  • ConfigurationPropertiesBindingPostProcessor — обрабатывает @ConfigurationProperties

5. Инициализация Bean'а

Этап инициализации может быть выполнен тремя способами:

Способ 1: @PostConstruct аннотация (рекомендуется)

@Component
public class MyBean {
    
    @PostConstruct
    public void init() {
        System.out.println("5a. @PostConstruct - Bean initialized");
    }
}

Способ 2: InitializingBean интерфейс

@Component
public class MyBean implements InitializingBean {
    
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("5b. InitializingBean.afterPropertiesSet()");
    }
}

Способ 3: init-method в XML конфигурации

public class MyBean {
    public void init() {
        System.out.println("5c. init-method called");
    }
}

6. BeanPostProcessor.postProcessAfterInitialization

Spring вызывает методы для POST-инициализации:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("6. postProcessAfterInitialization for " + beanName);
        return bean;
    }
}

Примеры использования: AOP, @Transactional, Custom логирование.

7. Bean готов к использованию

Теперь bean может быть внедрён в другие компоненты и использован.

8. Destruction (Уничтожение Bean'а)

Способ 1: @PreDestroy аннотация (рекомендуется)

@Component
public class MyBean {
    
    @PreDestroy
    public void cleanup() {
        System.out.println("8a. @PreDestroy - Cleanup resources");
    }
}

Способ 2: DisposableBean интерфейс

@Component
public class MyBean implements DisposableBean {
    
    @Override
    public void destroy() throws Exception {
        System.out.println("8b. DisposableBean.destroy()");
    }
}

Полный практический пример

import org.springframework.stereotype.Component;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;

@Component
public class CompleteBean implements InitializingBean, DisposableBean {
    
    public CompleteBean() {
        System.out.println("1. Constructor");
    }
    
    @PostConstruct
    public void postConstruct() {
        System.out.println("5. @PostConstruct - Primary init");
    }
    
    @Override
    public void afterPropertiesSet() {
        System.out.println("5. InitializingBean.afterPropertiesSet()");
    }
    
    @PreDestroy
    public void preDestroy() {
        System.out.println("8. @PreDestroy - Cleanup start");
    }
    
    @Override
    public void destroy() {
        System.out.println("8. DisposableBean.destroy() - Final cleanup");
    }
}

Порядок инициализации при наличии нескольких методов

Если использованы несколько способов инициализации:

1. @PostConstruct
2. InitializingBean.afterPropertiesSet()
3. init-method

Применяются в этом порядке, но обычно используется только один (предпочтительно @PostConstruct).

Scope и жизненный цикл

Жизненный цикл зависит от scope bean'а:

Singleton Scope (по умолчанию)

  • Создаётся при запуске контейнера
  • Инициализируется один раз
  • Уничтожается при закрытии контейнера
@Component
public class SingletonBean {
    @PostConstruct
    public void init() {
        System.out.println("Singleton init - один раз");
    }
}

Prototype Scope

  • Создаётся каждый раз при запросе
  • Инициализируется каждый раз
  • Spring НЕ вызывает @PreDestroy — ответственность на пользователе
@Component
public class PrototypeBean {
    @PostConstruct
    public void init() {
        System.out.println("Prototype init - каждый раз");
    }
}

Заключение

Жизненный цикл Spring Bean:

У8 этапов: Instantiation → Populate → Aware → Pre-Init → Init → Post-Init → Ready → Destroy

УИнициализация: @PostConstruct → InitializingBean → init-method

УУничтожение: @PreDestroy → DisposableBean → destroy-method

УПротotype beans: @PreDestroy не вызывается автоматически

УBeanPostProcessor: может кардинально изменить bean (AOP, Proxies)

Это глубокое знание требуется на интервью уровня Junior+ и является основой для понимания Spring фреймворка.

Какой жизненный цикл бина? | PrepBro