JavaRush /Курси /Модуль 5. Spring /Вступ до Spring Beans і життєвий цикл біна

Вступ до Spring Beans і життєвий цикл біна

Модуль 5. Spring
Рівень 1 , Лекція 9
Відкрита

1. Повторне знайомство зі Spring Beans

Spring Bean — це, по суті, об'єкт, яким керує IoC-контейнер Spring. Ці об'єкти створюються, ініціалізуються, налаштовуються, а також видаляються контейнером залежно від конфігурації програми. Якщо хочеш, щоб твій Java-об'єкт став частиною магії Spring, його треба зареєструвати як bean.

Уяви менеджера на складі, який завжди знає, де лежить потрібний тобі інструмент (або об'єкт). Ось таким менеджером і є IoC-контейнер, а інструменти на складі — це наші біни.

Як реєструються beans у Spring?

Є кілька способів зареєструвати біни:

  • Анотації (наприклад, @Component, @Service, @Repository).
  • Java-based конфігурація з використанням @Configuration і @Bean.
  • XML-конфігурація (так, вона все ще є, але використовується рідше — навіщо, коли є Java-анотації?).

Ось чому Spring гнучкий — обирай зручний спосіб реєстрації бінів.


2. Життєвий цикл Spring Bean

Біни, як і всі живі організми, мають життєвий цикл. Цей життєвий шлях включає етапи створення, ініціалізації, використання і видалення — все це контролюється IoC-контейнером. Давай розберемося, як це працює.

Основні етапи життєвого циклу

  1. Створення: bean створюється IoC-контейнером.
  2. Ініціалізація: у цей момент bean може налаштувати свої внутрішні стани.
  3. Використання: bean починає виконувати свою роботу (наприклад, обробляє запити).
  4. Видалення: як тільки bean більше не потрібен, контейнер видаляє його (якщо, звісно, це не singleton).

Візуалізація життєвого циклу


1. Створення об'єкта
          ↓
2. Встановлення залежностей (DI)
          ↓
3. Виклик методів ініціалізації (@PostConstruct)
          ↓
4. Використання біну
          ↓
5. Очищення ресурсів (@PreDestroy)

Тепер давай розглянемо конкретний приклад.


3. Як Spring керує життєвим циклом?

Для цього у Spring є зручні анотації. Познайомимося з ключовими з них.

Анотації @PostConstruct і @PreDestroy

  • @PostConstruct: виконує дії після створення bean і встановлення всіх його залежностей (наприклад, підключає сервіс або завантажує дані).
  • @PreDestroy: спрацьовує перед видаленням bean. Використовується для звільнення ресурсів (наприклад, закриття з'єднань).

Приклад:


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

@Component
public class LifecycleDemoBean {

    @PostConstruct
    public void init() {
        System.out.println("Бін ініціалізовано!");
    }

    public void doSomething() {
        System.out.println("Бін працює!");
    }

    @PreDestroy
    public void cleanup() {
        System.out.println("Бін знищено!");
    }
}

Коли Spring бачить анотації @PostConstruct і @PreDestroy, він гарантує, що ці методи будуть викликані у відповідні моменти.


Альтернатива з інтерфейсами InitializingBean і DisposableBean

Якщо віддаєш перевагу інтерфейсам замість анотацій (наприклад, для більш явного контракту), можна використати:

  • InitializingBean — метод afterPropertiesSet() викликається після створення bean.
  • DisposableBean — метод destroy() викликається перед видаленням bean.

Приклад:


import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class AlternativeLifecycleBean implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("Об'єкт налаштовано (InitializingBean)!");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("Об'єкт знищено (DisposableBean)!");
    }
}

Хоча такий підхід працює, у сучасних проєктах частіше використовують анотації @PostConstruct і @PreDestroy за їхню простоту і читабельність.


4. Керування бінaми за допомогою анотацій

@Component і компанія

  • @Component: загальна анотація для будь-якого біну, яку застосовують, якщо спеціалізована анотація не підходить.
  • @Service: для класів з бізнес-логікою.
  • @Repository: для класів, що відповідають за доступ до даних.
  • @Controller: для MVC-контролерів.

Приклад використання @Component:


@Component
public class SimpleBean {
    public void sayHello() {
        System.out.println("Привіт, світ бінів!");
    }
}

@Autowired і автоматичне впровадження залежностей

Ми вже трохи говорили про впровадження залежностей, але давай заглибимось.

  • @Autowired: дозволяє Spring автоматично налаштувати залежності.

Приклад роботи з @Autowired:


@Component
public class DependencyBean {
    public String getDependencyInfo() {
        return "Інформація про залежність.";
    }
}

@Component
public class AutowiredBean {

    private final DependencyBean dependency;

    @Autowired
    public AutowiredBean(DependencyBean dependency) {
        this.dependency = dependency;
    }

    public void printDependencyInfo() {
        System.out.println(dependency.getDependencyInfo());
    }
}

При запуску Spring сам знайде DependencyBean і передасть його в AutowiredBean.


5. Скоупи бінів

За замовчуванням усі біни в Spring мають scope singleton. Це означає, що існує тільки один екземпляр біна в IoC-контейнері. Але іноді треба керувати scope'ами.

Основні scope'и

  • Singleton: один бін на весь IoC-контейнер.
  • Prototype: новий об'єкт створюється щоразу, коли бін запитується.
  • Request: один екземпляр для кожного HTTP-запиту.
  • Session: один екземпляр для кожної HTTP-сесії.

Встановлення scope'у

Анотація @Scope дозволяє керувати життєвим циклом біна.


import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class PrototypeBean {
    public PrototypeBean() {
        System.out.println("Створено новий екземпляр PrototypeBean!");
    }
}

Кожного разу при використанні цього біна створюється новий екземпляр.


6. Типові помилки і як їх виправити

  1. Помилка через відсутність залежності: якщо використовуєш @Autowired, але бін не зареєстрований, Spring кине виняток NoSuchBeanDefinitionException. Рішення? Перевір, що бін зареєстрований через анотацію або конфігурацію.
  2. Видалення prototype-біну: Spring не керує життєвим циклом prototype-бінів, тому видаляй їх самостійно.
  3. Багато співпадінь бінів: якщо в тебе кілька бінів одного типу, Spring може заплутатися. Використовуй @Qualifier, щоб вказати конкретний бін.

Приклад @Qualifier:


@Component("catBean")
public class Cat {}

@Component("dogBean")
public class Dog {}

@Component
public class AnimalShelter {

    @Autowired
    @Qualifier("catBean") // Вказуємо, який бін використовувати
    private Cat pet;
}

Звідки ми це все знаємо?

Якщо хочеш копати глибше, ось кілька корисних посилань:


Хай живуть біни, життєвий цикл і те, що спрощує нам життя! Наступний крок — ще більше магії Spring!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ