Джерело зображення
Кастомні стартери у Spring Boot є важливою функцією, що полегшує управління залежностями та дозволяє розробникам пакувати повторно використовувані конфігурації для різних проєктів. У цій статті ми розглянемо, як працюють кастомні стартери Spring Boot, детально пояснюючи їх структуру, механізм автоконфігурації та інтеграцію з додатками.
Огляд стартерів Spring Boot
Стартери Spring Boot — це спеціалізовані модулі залежностей, призначені для того, щоб об'єднати колекцію бібліотек, конфігурацій та інших супутніх ресурсів в один узгоджений артефакт. Ці стартери є основою підходу Spring Boot до управління залежностями та модульного дизайну додатків, що дозволяє розробникам швидко інтегрувати та конфігурувати складні функції додатків без необхідності вручну вказувати чи налаштовувати кожну залежність.
Анатомія стартера Spring Boot
В основі стартерів лежать просто залежності Maven або Gradle з визначеною структурою та специфічними умовами. Вони призначені для того, щоб полегшити додавання кількох пов'язаних бібліотек шляхом упаковки їх в одну залежність.
Наприклад, стартер spring-boot-starter-web
включає:
- Spring MVC: для обробки веб-запитів.
- Jackson: для обробки JSON.
- Tomcat (або Jetty): як сервер за замовчуванням.
Це означає, що включення spring-boot-starter-web
у вашому проєкті автоматично додасть всі ці залежності разом з їх транзитивними залежностями, базуючись на конфігурації pom.xml
або build.gradle
стартеру.
Механізм вирішення залежностей
Коли стартер Spring Boot додається до проєкту, інструмент збірки (наприклад, Maven або Gradle) вирішує його залежності рекурсивно. Наприклад, якщо стартер вказує бібліотеку spring-web
як залежність, Maven завантажить цю бібліотеку та всі додаткові залежності, оголошені в її власному pom.xml
. Цей ієрархічний процес вирішення залежностей спрощує управління залежностями, але вимагає точного налаштування в модулі стартера, щоб уникнути конфліктів версій або зайвого навантаження.
Добре спроектований стартер залежить від:
- Виключень: для усунення конфліктуючих або небажаних транзитивних залежностей.
- Обмежень залежностей: для контролю версій основних бібліотек і забезпечення сумісності з усією екосистемою Spring.
Як стартери Spring Boot інтегруються з автоконфігурацією
Хоча стартери самі по собі упаковують бібліотеки, вони також слугують як каталізатори для автоконфігурації в Spring Boot. Коли стартер додається до проєкту, він часто працює в тандемі з механізмом автоконфігурації Spring Boot, який динамічно активує біні (beans) та конфігурації на основі наявності конкретних класів, властивостей або інших умов.
Наприклад:
- Додавши
spring-boot-starter-data-jpa
до вашого проєкту, ви отримаєте Hibernate як залежність. - Механізм автоконфігурації виявляє наявність Hibernate і автоматично конфігурує
DataSource
,EntityManagerFactory
та менеджер транзакцій.
Ця інтеграція між залежностями стартера та системою умовної конфігурації Spring Boot мінімізує необхідність ручного налаштування, спрощуючи процес узгодження середовища виконання додатку з його заявленими залежностями.
Переваги агрегації залежностей у стартерів
Агрегація залежностей у стартерів — це не лише зручність. Це відображає архітектурний принцип визначення узгоджених модулів, які інкапсулюють як функціональність, так і конфігурацію.
Цей підхід зменшує когнітивне навантаження для розробників, абстрагуючи вибір бібліотек, керування версіями та тестування сумісності.
Наприклад:
- Під час роботи з Spring Security додавання
spring-boot-starter-security
вводить базову конфігурацію, яка включає безпечні налаштування за замовчуванням, дозволяючи розробникам зосередитись на налаштуванні поведінки додатка, а не на його початковій конфігурації.
Створення кастомного модуля-стартера
Створення кастомного стартеру Spring Boot передбачає створення модуля, що надає повторно використовувану функціональність шляхом інкапсуляції залежностей, конфігурацій і додаткових ресурсів. Цей модуль інтегрується з екосистемою Spring Boot, дотримуючись встановлених умов та використовуючи механізм автоконфігурації для надання готової поведінки.
Ініціалізація модуля
Перший крок при створенні кастомного стартеру — це створення нового Maven або Gradle модуля. Цей модуль служить контейнером для залежностей та конфігурацій, які ви хочете упакувати. Модуль-стартер має мати тип пакування jar
і явно вказувати свої залежності у файлі pom.xml
або build.gradle
.
Maven pom.xml
:
com.example
custom-starter
1.0.0
jar
org.springframework.boot
spring-boot-autoconfigure
У цій конфігурації включено spring-boot-autoconfigure
, щоб надати доступ до фреймворку автоконфігурації Spring Boot, який є необхідним для більшості кастомних стартерів.
Структурування модуля-стартера
Кастомний стартер потребує специфічних структурних елементів для безперешкодної інтеграції з Spring Boot. Типова структура каталогів та файлів виглядає наступним чином:
src/main/java/com/example/config/
└── MyAutoConfiguration.java
src/main/resources/META-INF/
└── spring.factories
- Клас автоконфігурації: цей клас визначає біні (beans) і конфігурації, які надаються стартером.
- Файл
spring.factories
: цей файл необхідний для реєстрації класу автоконфігурації в механізмі автоконфігурації Spring Boot.
Додавання залежностей і виключень
Файл pom.xml
має визначати залежності, які стартер надасть споживаючим додаткам. Важливо ретельно вибирати ці залежності, щоб уникнути непотрібних транзитивних залежностей.
Приклад:
com.example
my-library
1.0.0
compile
org.springframework
spring-context
Виключення можуть бути використані для усунення будь-яких транзитивних залежностей, що можуть спричинити конфлікти або не потрібні споживаючому додатку.
Приклад виключення транзитивних залежностей:
com.example
my-library
1.0.0
org.slf4j
slf4j-api
Реєстрація автоконфігурації
Файл spring.factories
є критичним компонентом, що з’єднує модуль-стартер із системою автоконфігурації Spring Boot.
Цей файл повинен бути розміщений в директорії src/main/resources/META-INF/
і містити повні кваліфіковані імена класів автоконфігурації.
Приклад:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.MyAutoConfiguration
Цей файл вказує Spring Boot, що необхідно включити MyAutoConfiguration
в процес автоконфігурації, коли модуль-стартер знаходиться в classpath.
Реалізація класу автоконфігурації
Клас автоконфігурації — це місце, де визначається повторно використовувана функціональність. Він анотований як @Configuration
, щоб позначити його як клас конфігурації Spring, і часто використовує умовні анотації для контролю його активації.
Приклад:
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyAutoConfiguration {
@Bean
public MyService myService() {
return new MyService();
}
}
У наведеному прикладі визначено бін MyService
, який автоматично створюється та додається до контексту додатка, коли використовується стартер.
Тестування стартера
Тестування є важливим етапом для перевірки, чи правильно інтегрується стартер з додатками Spring Boot. Це можна зробити, створивши зразковий додаток, що включає стартер як залежність.
- Додайте кастомний стартер до
pom.xml
зразкового додатка:
com.example
custom-starter
1.0.0
- Перевірте, чи біні та конфігурації, надані стартером, завантажуються як очікується:
@SpringBootApplication
public class TestApplication {
public static void main(String[] args) {
ApplicationContext context = SpringApplication.run(TestApplication.class, args);
MyService myService = context.getBean(MyService.class);
System.out.println(myService.getMessage());
}
}
Дотримуючись цих кроків, ви зможете ефективно створити, упакувати та протестувати свій кастомний стартер, підготувавши його до інтеграції з додатками Spring Boot. Цей метод спрощує процес обміну повторно використовуваною функціональністю між проектами без надмірної конфігурації.
Автоконфігурація та інтеграція залежностей
Автоконфігурація — це основна функція Spring Boot, розроблена для динамічного налаштування контексту додатка на основі залежностей, доступних у classpath, та різних умов виконання. Цей механізм є основою для інтеграції кастомних модулів-стартерів, дозволяючи їм надавати попередньо налаштовану функціональність без необхідності вручну налаштовувати все розробнику.
Механізм автоконфігурації
Автоконфігурація працює через умовні анотації, класи конфігурації та механізм spring.factories
.
Коли додаток запускається, Spring Boot сканує класи автоконфігурації, вказані у файлі META-INF/spring.factories
, оцінює їх умови і застосовує їх до контексту додатка, якщо умови виконуються.
Завантажувач Spring Factories:
- Spring Boot використовує клас
SpringFactoriesLoader
для завантаження всіх повних імен класів, вказаних підorg.springframework.boot.autoconfigure.EnableAutoConfiguration
у файліspring.factories
. - Ці класи завантажуються в контекст додатка у вказаному порядку, що дозволяє здійснювати модульну та гнучку конфігурацію.
Приклад запису в spring.factories
:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.config.MyAutoConfiguration,\
com.example.config.OtherAutoConfiguration
Умовні анотації:
- Умовні анотації, як-от
@ConditionalOnClass
,@ConditionalOnMissingBean
та@ConditionalOnProperty
, визначають, чи має бути включений певний клас автоконфігурації або бін. - Ці умови дозволяють вибірково активувати конфігурацію в залежності від наявності певних класів, бінів або властивостей.
Приклад:
@Configuration
@ConditionalOnClass(name = "com.example.library.MyLibrary")
public class MyLibraryAutoConfiguration {
@Bean
public MyLibraryService myLibraryService() {
return new MyLibraryService();
}
}
У цьому прикладі бін MyLibraryService
реєструється тільки тоді, коли клас com.example.library.MyLibrary
присутній у classpath.
Інтеграція залежностей у стартери
Кастомні стартери часто надають не тільки конфігурації, але й бібліотеки, від яких залежить система автоконфігурації. Процес інтеграції включає:
Агрегація залежностей:
- Стартери включають всі необхідні бібліотеки як частину їх декларації залежностей, гарантуючи, що споживаючий додаток має все необхідне для роботи з автоконфігурацією стартера.
Приклад залежностей для стартера:
org.springframework
spring-context
com.example
my-library
Розв'язання транзитивних залежностей:
- Коли стартер додається до проєкту, інструмент для побудови рекурсивно розв'язує транзитивні залежності. Якщо
my-library
залежить від додаткових бібліотек, вони автоматично додаються до споживаючого додатка.
Виключення непотрібних залежностей:
- Для уникнення зайвих залежностей можна оголосити виключення у конфігурації залежностей стартера.
Приклад виключення залежностей:
com.example
my-library
org.slf4j
slf4j-api
Умовна конфігурація на основі властивостей
Поширений шаблон в автоконфігурації — це використання властивостей для контролю активації конкретних конфігурацій. Анотація @ConditionalOnProperty
дозволяє розробникам прив'язувати конфігурації до конкретних властивостей, визначених у конфігураційних файлах додатка.
Приклад:
@Configuration
@ConditionalOnProperty(name = "custom.feature.enabled", havingValue = "true")
public class FeatureAutoConfiguration {
@Bean
public FeatureService featureService() {
return new FeatureService();
}
}
У цьому випадку бін FeatureService
реєструється тільки тоді, коли властивість custom.feature.enabled
встановлена в значення true
у файлі application.properties
або application.yml
.
Інтеграційне тестування автоконфігурації
Після реалізації автоконфігурації тестування її поведінки є критичним для перевірки правильної інтеграції з екосистемою Spring Boot.
Інтеграційні тести можуть підтвердити, що очікувані біни завантажені на основі заданих умов.
Тестування за допомогою @SpringBootTest
:
@SpringBootTest(properties = "custom.feature.enabled=true")
class FeatureAutoConfigurationTest {
@Autowired
private FeatureService featureService;
@Test
void featureServiceShouldBeAvailable() {
assertNotNull(featureService);
}
}
Цей тест перевіряє, що бін FeatureService
реєструється в контексті додатка, коли властивість custom.feature.enabled
встановлена в значення true
.
Висновок
Системи кастомних стартерів залежностей і автоконфігурації в Spring Boot працюють через структурований і систематичний процес. Створення кастомного стартера передбачає визначення залежностей, правильну структуру модуля та використання умовних анотацій для динамічної активації конфігурацій на основі середовища виконання. Ці механізми дозволяють створювати повторно використовувані та контекстно специфічні модулі, які відповідають потребам різних проєктів. Така архітектура дає змогу будувати масштабовані та модульні додатки, зберігаючи гнучкість у інтеграції нових функціональностей.
Дякую за прочитання! Якщо ця стаття була корисною, будь ласка, розгляньте можливість підкреслити, аплодувати, відповісти або зв'язатися зі мною через Twitter/X це буде дуже приємно і допоможе тримати контент, подібний до цього, безкоштовним!
Іконка Spring Boot від Icons8
Перекладено з: How Spring Boot Implements Custom Starter Dependencies