Какой жизненный цикл у объектов в Spring?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Жизненный цикл объектов (Bean) в Spring
Обзор
Bean в Spring — это объект, управляемый контейнером Spring. Контейнер отвечает за создание, инициализацию, использование и уничтожение beans. Понимание жизненного цикла критично для корректной работы приложения.
Этапы жизненного цикла Bean
Этапы:
- Instantiation (Создание экземпляра)
- Setter injection (Внедрение зависимостей)
- BeanNameAware / BeanClassLoaderAware / BeanFactoryAware (Aware интерфейсы)
- Pre-initialization - BeanPostProcessor.postProcessBeforeInitialization()
- PostConstruct / afterPropertiesSet() / init-method (инициализация)
- Post-initialization - BeanPostProcessor.postProcessAfterInitialization()
- Bean готов к использованию
- PreDestroy / destroy() / destroy-method (уничтожение при выключении контекста)
Пример полного жизненного цикла
@Component
public class LifecycleBean implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
private String name;
// 1. Конструктор (Instantiation)
public LifecycleBean() {
System.out.println("1. Constructor called");
}
// 2. Setter injection
public void setName(String name) {
System.out.println("2. setName() called with: " + name);
this.name = name;
}
// 3. BeanNameAware - узнаём имя bean
@Override
public void setBeanName(String beanName) {
System.out.println("3. setBeanName() called with: " + beanName);
}
// 4. BeanFactoryAware - узнаём factory
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("4. setBeanFactory() called");
}
// 5. PostConstruct - инициализация (рекомендуется)
@PostConstruct
public void postConstruct() {
System.out.println("5. @PostConstruct called");
}
// 6. InitializingBean.afterPropertiesSet()
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("6. afterPropertiesSet() called");
}
// 7. Bean готов к использованию
public void doSomething() {
System.out.println("7. Bean is in use, name = " + name);
}
// 8. PreDestroy - уничтожение (рекомендуется)
@PreDestroy
public void preDestroy() {
System.out.println("8. @PreDestroy called");
}
// 9. DisposableBean.destroy()
@Override
public void destroy() throws Exception {
System.out.println("9. destroy() called");
}
}
BeanPostProcessor - расширение жизненного цикла
BeanPostProcessor позволяет обработать beans ДО и ПОСЛЕ инициализации:
@Component
public class CustomBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Pre-init BeanPostProcessor: " + beanName);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("Post-init BeanPostProcessor: " + beanName);
return bean;
}
}
Scopes Bean (область видимости)
Scope определяет, сколько экземпляров bean создаст Spring:
Singleton (по умолчанию)
Один экземпляр на весь ApplicationContext:
@Component
@Scope("singleton")
public class SingletonBean {
public void show() {
System.out.println("Singleton Bean");
}
}
SingletonBean bean1 = context.getBean(SingletonBean.class);
SingletonBean bean2 = context.getBean(SingletonBean.class);
assert bean1 == bean2; // true - тот же объект
Prototype
Новый экземпляр при каждом запросе:
@Component
@Scope("prototype")
public class PrototypeBean {
public void show() {
System.out.println("Prototype Bean");
}
}
PrototypeBean bean1 = context.getBean(PrototypeBean.class);
PrototypeBean bean2 = context.getBean(PrototypeBean.class);
assert bean1 != bean2; // true - разные объекты
Request (в веб-приложениях)
Новый экземпляр на каждый HTTP запрос:
@Component
@Scope("request")
public class RequestBean {
// Это разные объекты для каждого запроса
}
Session
Один экземпляр на HTTP сессию:
@Component
@Scope("session")
public class SessionBean {
// Один объект для всей сессии пользователя
}
Инициализация Bean - рекомендуемые подходы
Лучший способ - @PostConstruct:
@Component
public class InitService {
@PostConstruct
public void init() {
System.out.println("Bean initialized");
}
}
Альтернативные способы:
- InitializingBean интерфейс
- init-method в XML конфигурации
- Bean с initMethod параметром
Уничтожение Bean
Лучший способ - @PreDestroy:
@Component
public class ResourceService {
private Connection connection;
@PostConstruct
public void init() {
this.connection = createConnection();
}
@PreDestroy
public void cleanup() {
if (connection != null) {
connection.close();
}
}
}
Практический пример - Database Connection Pool
@Component
public class DataSourceBean {
private DataSource dataSource;
private HikariPool pool;
@PostConstruct
public void initializeDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
config.setUsername("user");
config.setPassword("pass");
config.setMaximumPoolSize(20);
this.pool = new HikariPool(config);
this.dataSource = pool.getDataSource();
}
public DataSource getDataSource() {
return dataSource;
}
@PreDestroy
public void closeDataSource() {
if (pool != null) {
pool.close();
}
}
}
Заключение
Понимание жизненного цикла Bean критично для написания надёжного Spring кода. Используй @PostConstruct для инициализации и @PreDestroy для очистки ресурсов. Знай разницу между Singleton и Prototype scopes. Всегда закрывай ресурсы при выключении.