Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Вивчайте IoC та DI | Основи Spring Boot
Spring Boot Backend

bookIoC та DI

Spring Container — це центральний компонент Spring Framework, який керує створенням, конфігурацією та життєвим циклом бінів (об'єктів) у додатку. Spring Container також відомий як IoC контейнер.

Залежність — це будь-який клас, якому для коректної роботи потрібно ін'єктувати інші об'єкти, і цей ланцюг залежностей може бути безкінечним. Зазвичай, щоб створити об'єкт із залежностями, необхідно явно ініціалізувати його за допомогою оператора new і вказати клас.

Саме тут у гру вступає Spring із концепціями Inversion of Control та Dependency Injection. Ідея полягає в тому, що Spring бере на себе відповідальність за створення та керування залежностями. Замість ручного налаштування ми просто анотуємо потрібні класи, і Spring автоматично створює їх і керує їхнім життєвим циклом у своєму контексті.

Однією з таких анотацій є @Component, яку розміщують над класом.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Цей підхід зміщує фокус від ручного керування залежностями, дозволяючи розробникам зосередитися на бізнес-логіці, у той час як Spring бере на себе інфраструктурні завдання, пов'язані зі створенням об'єктів та керуванням залежностями.

Як працює контейнер Spring?

Під час запуску застосунку ініціалізується Spring Container. Він починає сканувати класи на наявність анотацій таких як @Component, @Service, @Repository та @Configuration.

@Component — це загальна анотація, яка робить клас керованим у Spring, дозволяючи йому бути зареєстрованим як bean.

@Service, @Repository та @Controller — це більш спеціалізовані версії @Component. Виконують ту ж функцію, але вказують на конкретну роль класу: @Service для бізнес-логіки, @Repository для доступу до даних, а @Controller для обробки веб-запитів.

@Configuration використовується для класів, які містять визначення bean-ів та конфігурацію застосунку.

Позначення класу однією з цих анотацій гарантує, що він стане bean-ом у Spring context.

Після ідентифікації класів контейнер переходить до створення екземплярів цих анотованих класів, фактично перетворюючи їх на біни, якими Spring-контекст керує протягом усього життєвого циклу додатка.

Під час створення цих бінів контейнер автоматично керує їхніми залежностями за допомогою ін'єкції залежностей. Цей процес дозволяє класам отримувати необхідні залежності без потреби їх явного створення чи пошуку, що спрощує процес розробки.

Ін'єкція залежностей (DI)

Спочатку Spring Container додає до свого контексту біни (класи), позначені анотаціями @Component, @Service, @Repository та @Configuration. Після цього він надає ці біни будь-яким об'єктам, які їх запитують.

Приклад із реального життя

Уявіть, що ви розробляєте інтернет-магазин. У вас є клас OrderService, який керує замовленнями, та клас PaymentService, який опрацьовує платежі. Замість того, щоб вручну створювати екземпляр PaymentService всередині OrderService, можна дозволити Spring Container створити та інжектувати PaymentService у OrderService.

OrderService.java

OrderService.java

PaymentService.java

PaymentService.java

copy
1234567891011121314
@Service public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

У класі OrderService буде поле paymentService, яке ініціалізується саме тим типом, який нам потрібен (PaymentService). Зверніть увагу, що ми не ініціалізували цей об'єкт вручну — Spring зробив це за нас!

Якби ми не позначили PaymentService анотацією @Service, цей bean не був би доданий до контексту Spring, і ми отримали б помилку про те, що Spring не може знайти такий bean.

@Autowired

Можна також використовувати анотацію @Autowired, яка вказує Spring Container впровадити відповідний об'єкт у поле.

OrderService.java

OrderService.java

copy
123456789101112131415
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

У Spring, починаючи з версії 4.3, використання анотації @Autowired більше не є обов’язковим при впровадженні залежностей через конструктор, якщо у класі є лише один конструктор. Spring автоматично визначає, що саме цей конструктор слід використовувати для ін’єкції залежностей.

Які існують типи Bean?

Уявіть, що у вас є одна кавова машина в кафе. Коли клієнт замовляє каву, бариста використовує цю ж кавову машину для приготування кожної чашки. Кавова машина завжди та сама, а не нова для кожного замовлення.

Аналогічно, у Spring, коли ви ін’єктуєте bean із Spring context, Spring надає вам ту ж саму інстанцію цього bean щоразу. Це називається singleton scope. Як і з кавовою машиною у кафе, Spring гарантує, що ви завжди отримуєте той самий об’єкт, а не створюєте новий кожного разу.

Сінглтон

Можна встановити тип за допомогою анотації @Scope і вказати singleton у атрибутах.

SingletonService.

SingletonService.

copy
12345
@Service @Scope("singleton") public class SingletonService { // Class for handling business logic }

Прототип

PrototypeService.java

PrototypeService.java

copy
12345
@Service @Scope("prototype") public class PrototypeService { // Class for handling business logic }

Виконуємо те саме, але вказуємо prototype у атрибутах. Це гарантує, що кожного разу, коли ми інжектимо цей bean, буде повертатися новий об'єкт.

Підсумок

У цьому розділі про IoC (Inversion of Control) та DI (Dependency Injection) ми розглянули, як Spring керує створенням і життєвим циклом бінів за допомогою свого контейнера, забезпечуючи автоматичне впровадження залежностей.

Ми обговорили стандартну область видимості singleton, де один екземпляр біна використовується повторно, та область prototype, яка створює новий екземпляр для кожного запиту, підкреслюючи, як ці області впливають на керування об'єктами та архітектуру застосунку.

1. Що таке Inversion of Control (IoC) у Spring?

2. Який принцип лежить в основі Dependency Injection (DI)?

question mark

Що таке Inversion of Control (IoC) у Spring?

Select the correct answer

question mark

Який принцип лежить в основі Dependency Injection (DI)?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 4

Запитати АІ

expand

Запитати АІ

ChatGPT

Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат

Awesome!

Completion rate improved to 3.45

bookIoC та DI

Свайпніть щоб показати меню

Spring Container — це центральний компонент Spring Framework, який керує створенням, конфігурацією та життєвим циклом бінів (об'єктів) у додатку. Spring Container також відомий як IoC контейнер.

Залежність — це будь-який клас, якому для коректної роботи потрібно ін'єктувати інші об'єкти, і цей ланцюг залежностей може бути безкінечним. Зазвичай, щоб створити об'єкт із залежностями, необхідно явно ініціалізувати його за допомогою оператора new і вказати клас.

Саме тут у гру вступає Spring із концепціями Inversion of Control та Dependency Injection. Ідея полягає в тому, що Spring бере на себе відповідальність за створення та керування залежностями. Замість ручного налаштування ми просто анотуємо потрібні класи, і Spring автоматично створює їх і керує їхнім життєвим циклом у своєму контексті.

Однією з таких анотацій є @Component, яку розміщують над класом.

BeanExample.java

BeanExample.java

copy
123
@Component public class BeanExample { }

Цей підхід зміщує фокус від ручного керування залежностями, дозволяючи розробникам зосередитися на бізнес-логіці, у той час як Spring бере на себе інфраструктурні завдання, пов'язані зі створенням об'єктів та керуванням залежностями.

Як працює контейнер Spring?

Під час запуску застосунку ініціалізується Spring Container. Він починає сканувати класи на наявність анотацій таких як @Component, @Service, @Repository та @Configuration.

@Component — це загальна анотація, яка робить клас керованим у Spring, дозволяючи йому бути зареєстрованим як bean.

@Service, @Repository та @Controller — це більш спеціалізовані версії @Component. Виконують ту ж функцію, але вказують на конкретну роль класу: @Service для бізнес-логіки, @Repository для доступу до даних, а @Controller для обробки веб-запитів.

@Configuration використовується для класів, які містять визначення bean-ів та конфігурацію застосунку.

Позначення класу однією з цих анотацій гарантує, що він стане bean-ом у Spring context.

Після ідентифікації класів контейнер переходить до створення екземплярів цих анотованих класів, фактично перетворюючи їх на біни, якими Spring-контекст керує протягом усього життєвого циклу додатка.

Під час створення цих бінів контейнер автоматично керує їхніми залежностями за допомогою ін'єкції залежностей. Цей процес дозволяє класам отримувати необхідні залежності без потреби їх явного створення чи пошуку, що спрощує процес розробки.

Ін'єкція залежностей (DI)

Спочатку Spring Container додає до свого контексту біни (класи), позначені анотаціями @Component, @Service, @Repository та @Configuration. Після цього він надає ці біни будь-яким об'єктам, які їх запитують.

Приклад із реального життя

Уявіть, що ви розробляєте інтернет-магазин. У вас є клас OrderService, який керує замовленнями, та клас PaymentService, який опрацьовує платежі. Замість того, щоб вручну створювати екземпляр PaymentService всередині OrderService, можна дозволити Spring Container створити та інжектувати PaymentService у OrderService.

OrderService.java

OrderService.java

PaymentService.java

PaymentService.java

copy
1234567891011121314
@Service public class OrderService { private final PaymentService paymentService; public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

У класі OrderService буде поле paymentService, яке ініціалізується саме тим типом, який нам потрібен (PaymentService). Зверніть увагу, що ми не ініціалізували цей об'єкт вручну — Spring зробив це за нас!

Якби ми не позначили PaymentService анотацією @Service, цей bean не був би доданий до контексту Spring, і ми отримали б помилку про те, що Spring не може знайти такий bean.

@Autowired

Можна також використовувати анотацію @Autowired, яка вказує Spring Container впровадити відповідний об'єкт у поле.

OrderService.java

OrderService.java

copy
123456789101112131415
@Service public class OrderService { private final PaymentService paymentService; @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } public void placeOrder() { System.out.println("Placing order..."); paymentService.processPayment(); } }

У Spring, починаючи з версії 4.3, використання анотації @Autowired більше не є обов’язковим при впровадженні залежностей через конструктор, якщо у класі є лише один конструктор. Spring автоматично визначає, що саме цей конструктор слід використовувати для ін’єкції залежностей.

Які існують типи Bean?

Уявіть, що у вас є одна кавова машина в кафе. Коли клієнт замовляє каву, бариста використовує цю ж кавову машину для приготування кожної чашки. Кавова машина завжди та сама, а не нова для кожного замовлення.

Аналогічно, у Spring, коли ви ін’єктуєте bean із Spring context, Spring надає вам ту ж саму інстанцію цього bean щоразу. Це називається singleton scope. Як і з кавовою машиною у кафе, Spring гарантує, що ви завжди отримуєте той самий об’єкт, а не створюєте новий кожного разу.

Сінглтон

Можна встановити тип за допомогою анотації @Scope і вказати singleton у атрибутах.

SingletonService.

SingletonService.

copy
12345
@Service @Scope("singleton") public class SingletonService { // Class for handling business logic }

Прототип

PrototypeService.java

PrototypeService.java

copy
12345
@Service @Scope("prototype") public class PrototypeService { // Class for handling business logic }

Виконуємо те саме, але вказуємо prototype у атрибутах. Це гарантує, що кожного разу, коли ми інжектимо цей bean, буде повертатися новий об'єкт.

Підсумок

У цьому розділі про IoC (Inversion of Control) та DI (Dependency Injection) ми розглянули, як Spring керує створенням і життєвим циклом бінів за допомогою свого контейнера, забезпечуючи автоматичне впровадження залежностей.

Ми обговорили стандартну область видимості singleton, де один екземпляр біна використовується повторно, та область prototype, яка створює новий екземпляр для кожного запиту, підкреслюючи, як ці області впливають на керування об'єктами та архітектуру застосунку.

1. Що таке Inversion of Control (IoC) у Spring?

2. Який принцип лежить в основі Dependency Injection (DI)?

question mark

Що таке Inversion of Control (IoC) у Spring?

Select the correct answer

question mark

Який принцип лежить в основі Dependency Injection (DI)?

Select the correct answer

Все було зрозуміло?

Як ми можемо покращити це?

Дякуємо за ваш відгук!

Секція 2. Розділ 4
some-alt