В каком виде запускается Spring Boot приложение без реактивного стека и WebFlux
Что проверяют
Понимаете ли вы, что происходит между main и первым обработанным запросом. Вопрос про сервлетный стек, и по ответу видно, отличаете ли вы его от реактивного.
Как отвечать
Без WebFlux приложение поднимается как обычное сервлетное. Цепочка такая:
- точка входа: класс с
@SpringBootApplicationиSpringApplication.run(...)в методеmain. Приложение собирается в исполняемый jar с зависимостями внутри и запускается какjava -jar app.jar, отдельный сервер приложений не нужен; - выбор типа контекста: Spring Boot смотрит classpath. Есть
spring-boot-starter-webи сервлетный API, значит поднимаетсяAnnotationConfigServletWebServerApplicationContextи встроенный контейнер, по умолчанию Tomcat (альтернативы Jetty и Undertow); - веб-слой: регистрируется
DispatcherServlet, который раздаёт запросы контроллерам черезHandlerMapping, конвертирует тела запросов и ответов, обрабатывает исключения через@ControllerAdvice; - модель работы: поток на запрос. Пул потоков Tomcat, блокирующие вызовы к базе через JDBC, простая отладка и понятный стек вызовов. В реактивном стеке вместо этого цикл событий и неблокирующие вызовы;
- упаковка в war остаётся возможной: класс наследует
SpringBootServletInitializer, и приложение разворачивается во внешнем контейнере. Это нужно редко.
Полезно добавить: начиная со Spring Boot 3.2 сервлетный стек умеет работать на виртуальных потоках (spring.threads.virtual.enabled=true), что снимает часть возражений про блокирующую модель.
Где спотыкаются
Думают, что без WebFlux нужен внешний Tomcat. Сервер встроен в jar.
Смешивают стеки: WebClient и Mono в сервлетном приложении работают, но не делают его реактивным, а блокирующий вызов внутри реактивной цепочки, наоборот, всё портит.
Не могут назвать DispatcherServlet, хотя именно он и есть точка входа веб-слоя.