Що таке автоконфігурація в Spring Boot
Принцип роботи формулюється як Convention over Configuration (Конвенція понад конфігурацію): замість написання сотень рядків XML або Java-конфігурації Spring Boot бере на себе р...
🟢 Junior Level
Автоконфігурація (Auto-Configuration) — це ключовий механізм Spring Boot, який автоматично створює, зв’язує та налаштовує біни в ApplicationContext на основі бібліотек, виявлених у classpath, системних властивостей (application.properties / application.yml) та вже оголошених розробником компонентів.
Принцип роботи формулюється як Convention over Configuration (Конвенція понад конфігурацію): замість написання сотень рядків XML або Java-конфігурації Spring Boot бере на себе рутину з розумними налаштуваннями за замовчуванням (Opinionated Defaults).
Базовий приклад: підключення БД
У класичному Spring Framework для підключення до PostgreSQL потрібно було вручну налаштовувати DataSource, EntityManagerFactory, TransactionManager та пул HikariCP:
// Класичний Spring (без Spring Boot) — десятки рядків шаблонного коду:
@Configuration
public class ManualDbConfig {
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:postgresql://localhost:5432/mydb");
config.setUsername("user");
config.setPassword("pass");
return new HikariDataSource(config);
}
}
У Spring Boot достатньо:
- Додати стартер у
pom.xml/build.gradle:spring-boot-starter-data-jpaта драйверpostgresql. - Вказати параметри підключення в
application.yml:spring: datasource: url: jdbc:postgresql://localhost:5432/mydb username: user password: pass - Spring Boot сам виявить клас
org.postgresql.Driverі бібліотекуHikariDataSourceв classpath та створить готовий до роботи бінDataSource.
Як вимкнути непотрібну автоконфігурацію
// Вимкнення через анотацію:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Або через конфігураційний файл:
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
🟡 Middle Level
Пайплайн запуску автоконфігурації
Процес запуску автоконфігурації координується мета-анотацією @SpringBootApplication:
@SpringBootApplication
│
├──> @Configuration
├──> @ComponentScan (Сканує користувацькі біни)
└──> @EnableAutoConfiguration
│
▼
AutoConfigurationImportSelector
│
▼
Читання реєстру автоконфігурацій (.imports / spring.factories)
│
▼
Фільтрація за умовами (@Conditional)
│
▼
Реєстрація конфігурацій, що залишилися, в ApplicationContext
Сімейство анотацій @Conditional
Автоконфігурація працює завдяки умовним анотаціям (Conditions). Бін створюється тільки у разі виконання певного критерію:
| Анотація | Умова спрацьовування |
|---|---|
@ConditionalOnClass(Foo.class) |
Клас Foo фізично знайдено в classpath. |
@ConditionalOnMissingClass |
Класу немає в classpath. |
@ConditionalOnBean(Bar.class) |
У контексті вже є хоча б один бін зазначеного типу. |
@ConditionalOnMissingBean |
У контексті ще немає біна такого типу (дозволяє розробнику перевизначити бін). |
@ConditionalOnProperty |
В application.yml задано властивість із певним значенням. |
@ConditionalOnWebApplication |
Додаток є веб-додатком (сервлетним або реактивним). |
Приклад із вихідного коду Spring Boot: JacksonAutoConfiguration
@AutoConfiguration
@ConditionalOnClass(ObjectMapper.class) // Спрацює, лише якщо підключено Jackson
public class JacksonAutoConfiguration {
@Bean
@Primary
@ConditionalOnMissingBean // Створить ObjectMapper ТІЛЬКИ якщо розробник не оголосив свій!
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
return builder.createXmlMapper(false).build();
}
}
Золоте правило: Анотація
@ConditionalOnMissingBean— фундамент гнучкості Spring Boot. Вона означає: «Якщо програміст не оголосив власний бін, контейнер надасть дефолтний».
Налагодження автоконфігурації: Condition Evaluation Report
Щоб точно зрозуміти, чому певний бін створився або був пропущений, запустіть додаток із прапорцем --debug:
java -jar myapp.jar --debug
У консоль виведеться докладний звіт CONDITIONS EVALUATION REPORT:
- Positive matches: автоконфігурації, чиї умови виконано.
- Negative matches: автоконфігурації, які було пропущено (із зазначенням точної причини, наприклад:
@ConditionalOnClass did not find [org.apache.kafka.clients.producer.Producer]). - Exclusions: виключені конфігурації.
🔴 Senior Level
Еволюція механізмів: Spring Boot 2.x vs Spring Boot 3.x
До версії Spring Boot 2.7 для виявлення автоконфігурацій використовувався файл META-INF/spring.factories.
У Spring Boot 3.x цей механізм було замінено на спеціалізований файл реєстру:
Spring Boot 2.x:
META-INF/spring.factories
Ключ: org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
Spring Boot 3.x (та 2.7+):
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
Вміст: простий список повних імен класів по одному на рядок:
com.example.MyAutoConfiguration
Чому формат було змінено:
- Підтримка GraalVM Native Image та Spring AOT: простий список класів набагато швидше аналізується статичними аналізаторами під час Ahead-Of-Time компіляції.
- Продуктивність холодного старту: виключено оверхед на парсинг важкого Properties-файлу з багатьма різними SPI-ключами.
Як Spring Boot перевіряє @ConditionalOnClass без ClassNotFoundException
Якби Spring Boot перевіряв наявність класів через звичайний Class.forName("org.postgresql.Driver"), відсутній драйвер призвів би до викидання винятку ClassNotFoundException та аварійної зупинки додатка.
Внутрішній механізм:
Spring Boot аналізує метадані класів автоконфігурації через низькорівневий парсер байткоду ASM (SimpleMetadataReaderFactory), не завантажуючи самі класи в JVM Metaspace! Якщо ASM бачить, що цільовий тип відсутній у ClassLoader, гілка конфігурації відкидається ще до завантаження класу конфігурації.
Порядок фаз: Чому @ComponentScan виконується ДО автоконфігурації
Це фундаментальний архітектурний принцип:
- Спочатку відпрацьовує
@ComponentScan: контейнер знаходить і реєструє всі користувацькі біни, позначені@Component,@Service,@Repository,@Bean. - Тільки після цього запускається
AutoConfigurationImportSelector. - Завдяки цьому, коли автоконфігурація доходить до умов
@ConditionalOnMissingBean, вона вже «бачить» усі біни, створені розробником, і поступається їм пріоритетом.
Управління порядком автоконфігурацій: @AutoConfiguration
Для координації залежностей між різними автоконфігураціями використовується анотація @AutoConfiguration (яка прийшла на зміну @Configuration у стартерах):
package com.example.autoconfigure;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
@AutoConfiguration(after = DataSourceAutoConfiguration.class) // Запуститься СТРОГО ПІСЛЯ бази даних
@ConditionalOnClass(CustomAuditClient.class)
public class CustomAuditAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CustomAuditClient customAuditClient() {
return new CustomAuditClient();
}
}
🎯 Шпаргалка для інтерв’ю
30-секундна відповідь
Автоконфігурація — механізм Spring Boot, що реалізує підхід Convention over Configuration. Він автоматично реєструє біни в контексті на основі бібліотек у
classpath, властивостей конфігурації та поточного оточення.
- Ініціюється мета-анотацією
@EnableAutoConfigurationчерез класAutoConfigurationImportSelector.- У Spring Boot 3.x список автоконфігурацій зчитується з файлу
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports.- Реєстрація бінів керується сімейством анотацій
@Conditional(головна з яких —@ConditionalOnMissingBean, яка дозволяє користувачеві перевизначати дефолтні біни).- Користувацькі біни з
@ComponentScanреєструються першими, а автоконфігурація підключається після них.
4 каверзних питання з відповідями
-
Як Spring Boot перевіряє умови
@ConditionalOnClass, не викликаючиClassNotFoundException? Відповідь: Spring Boot використовує бібліотеку ASM для читання байткоду (.classфайлів) без фактичного завантаження класів у пам’ять через ClassLoader. За допомогоюMetadataReaderконтейнер аналізує константний пул та сигнатури типів. Якщо клас не може бути розв’язаний ClassLoader-ом, умова бракується без фатальної помилки. -
Чому автоконфігурації завжди запускаються ПІСЛЯ користувацьких класів конфігурації? Відповідь: Щоб розробник додатка мав найвищий пріоритет. Спочатку виконується сканування компонентів додатка (
@ComponentScan). Коли всі кастомні біни зареєстровано, запускається автоконфігурація, в якій спрацьовують анотації@ConditionalOnMissingBean. Якщо користувач уже створив свій бін, автоконфігурація мирно відступає. -
У чому різниця між
META-INF/spring.factoriesта.imports-файлом у Spring Boot 3? Відповідь: У Spring Boot 2.x усі точки розширення (включно зEnableAutoConfiguration) зберігалися в спільному файліspring.factoriesформату Java Properties. У Spring Boot 3.x автоконфігурації винесено в окремий текстовий файлMETA-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports, що являє собою простий список класів. Це прискорює старт додатка і необхідно для підтримки компіляції в Native Image (GraalVM / Spring AOT). -
Як визначити, чому конкретна автоконфігурація не застосувалася до вашого проєкту? Відповідь: Запустити додаток із параметром
--debug(абоdebug=trueвapplication.properties) чи викликати ендпоінт Spring Boot Actuator/actuator/conditions. У консолі з’явитьсяConditionEvaluationReport, де в розділіNegative matchesзазначено конкретну невиконану умову (наприклад, відсутність класу або властивості).
Червоні прапорці (чого категорично не можна говорити)
- ❌ «Автоконфігурація створює абсолютно всі біни з усіх стартерів у пам’яті» — створюються лише ті біни, для яких виконано всі умови
@Conditional. - ❌ «У Spring Boot 3.x для написання стартера все ще потрібно використовувати
spring.factories» — у Boot 3.x автоконфігурації оголошуються через.imports-файли. - ❌ «Автоконфігурація сповільнює виконання HTTP-запитів у рантаймі» — автоконфігурація працює строго один раз під час старту додатка і ніяк не впливає на продуктивність у runtime.
- ❌ «
@ConditionalOnMissingBeanсканує бібліотеки вclasspath» — ця анотація перевіряє наявність біна в поточномуApplicationContext, а не файли на диску.