Как работает @SpringBootApplication?
4. exclude → отключение автоконфигураций 5. basePackageClasses → типобезопасное сканирование 6. FailureAnalyzer → свои сообщения об ошибках
🟢 Junior Level
@SpringBootApplication — главная аннотация Spring Boot приложения.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Она делает 3 вещи:
- @Configuration → класс является конфигурацией
- @EnableAutoConfiguration → Spring Boot сам настраивает бины
- @ComponentScan → сканирует пакеты и находит @Component, @Service
Правило:
- Размещайте в корневом пакете
- Все подпакеты будут просканированы
🟡 Middle Level
Анатомия
@SpringBootConfiguration // = @Configuration для тестов
@EnableAutoConfiguration // Автоконфигурация
@ComponentScan // Сканирование пакетов
public @interface SpringBootApplication { }
ComponentScan поведение
// Application в com.example.app
// → Сканирует com.example.app и все подпакеты
// ❌ Сервисы в com.example.common → НЕ найдутся!
// ✅ Решение:
@SpringBootApplication(scanBasePackages = "com.example")
Процесс запуска
SpringApplication.run():
1. Создание ApplicationContext → контейнер для всех бинов
2. Загрузка Environment → application.properties, переменные окружения, CLI-аргументы
3. Refresh Context → ядро Spring: регистрирует BPP, создаёт ВСЕ бины, разрешает зависимости
4. Запуск встроенного сервера → Tomcat/Jetty/Undertow на указанном порту
5. Выполнение CommandLineRunner → ваш код после полного старта контекста
proxyBeanMethods
// По умолчанию: true (CGLIB прокси)
// Для оптимизации:
@SpringBootConfiguration(proxyBeanMethods = false)
// → Быстрее старт, меньше памяти: по умолчанию Spring создаёт CGLIB-подкласс
// для каждого @Configuration класса (Full mode). Генерация байт-кода занимает
// время и память. При proxyBeanMethods = false вызовы @Bean методов идут напрямую.
// → Но @Bean методы создают новые объекты при вызове
🔴 Senior Level
Refresh Context
Сердце запуска:
1. BeanFactoryPostProcessor → изменение BeanDefinition
2. BeanPostProcessor регистрация
3. Сканирование + автоконфигурация
4. Создание бинов
5. Запуск сервера
FailureAnalyzers
Spring Boot ловит ошибки старта:
→ "Port already in use"
→ "DataSource not configured"
→ Красивые сообщения вместо стек-трейса
→ Можно создать свои анализаторы
Production Experience
Реальный сценарий: ComponentScan не нашёл бины
Application → com.example.app
Services → com.example.services
→ Бины не найдены!
Решение:
@SpringBootApplication(scanBasePackages = "com.example")
Best Practices
- Корневой пакет → com.example.app
- scanBasePackages → если бины в других пакетах
- proxyBeanMethods = false — если @Bean методы не вызывают друг друга (иначе сломается singleton-семантика: каждый вызов создаст новый объект).
- exclude → отключение автоконфигураций
- basePackageClasses → типобезопасное сканирование
- FailureAnalyzer → свои сообщения об ошибках
Резюме для Senior
- @SpringBootApplication = Configuration + AutoConfig + ComponentScan
- Местоположение → определяет область сканирования
- Refresh Context → ключевая фаза создания бинов
- proxyBeanMethods → оптимизация старта
- FailureAnalyzers → понятные ошибки
- scanBasePackages → для бинов вне корневого пакета
🎯 Шпаргалка для интервью
Обязательно знать:
- @SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan
- Размещать в корневом пакете — сканирует все подпакеты
- SpringApplication.run(): создание контекста → загрузка Environment → Refresh Context → запуск сервера → CommandLineRunner
- proxyBeanMethods = false ускоряет старт, но ломает singleton при вызовах @Bean методов друг друга
- scanBasePackages / basePackageClasses — если бины вне корневого пакета
- Refresh Context — ключевая фаза: BPP регистрация, автоконфигурация, создание бинов
- FailureAnalyzers дают читаемые ошибки вместо стек-трейса
Частые уточняющие вопросы:
- Что произойдёт, если разместить Application не в корневом пакете? — Компоненты в других ветках пакетов не будут найдены ComponentScan.
- Зачем нужен proxyBeanMethods? — CGLIB-прокси обеспечивает singleton-семантику при вызовах @Bean методов; отключение ускоряет старт.
- Можно ли отключить автоконфигурацию? — Да, через @SpringBootApplication(exclude = …).
- Что делает Refresh Context? — Регистрирует BeanPostProcessor, создаёт все бины, запускает сервер.
Красные флаги (НЕ говорить):
- «@SpringBootApplication просто запускает приложение» — нет, это 3 аннотации в одной.
- «Можно ставить @SpringBootApplication на любой класс» — только на конфигурационный класс с main().
- «proxyBeanMethods = false всегда лучше» — нет, сломается singleton при меж-@Bean вызовах.
- «ComponentScan загружает все классы в JVM» — нет, ASM читает только байт-код.
Связанные темы:
- [[23. Что делает аннотация @ComponentScan]]
- [[24. Что такое @Configuration класс]]
- [[22. Что такое starter в Spring Boot]]
- [[26. Что делает аннотация @Autowired]]