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

Какой жизненный цикл у объектов в Spring?

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

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

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

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

# Жизненный цикл объектов (Bean) в Spring

Обзор

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

Этапы жизненного цикла Bean

Этапы:

  1. Instantiation (Создание экземпляра)
  2. Setter injection (Внедрение зависимостей)
  3. BeanNameAware / BeanClassLoaderAware / BeanFactoryAware (Aware интерфейсы)
  4. Pre-initialization - BeanPostProcessor.postProcessBeforeInitialization()
  5. PostConstruct / afterPropertiesSet() / init-method (инициализация)
  6. Post-initialization - BeanPostProcessor.postProcessAfterInitialization()
  7. Bean готов к использованию
  8. 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");
    }
}

Альтернативные способы:

  1. InitializingBean интерфейс
  2. init-method в XML конфигурации
  3. 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. Всегда закрывай ресурсы при выключении.

Какой жизненный цикл у объектов в Spring? | PrepBro