Какой класс запускает методы у Controller в Spring?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какой класс запускает методы у Controller в Spring?
Это фундаментальный вопрос о том, как Spring обрабатывает HTTP запросы и маршрутизирует их к методам контроллеров. Ответ — это DispatcherServlet, но давайте разберемся глубже.
Главный класс: DispatcherServlet
DispatcherServlet — это центральный сервлет, который перехватывает все входящие HTTP запросы и маршрутизирует их к соответствующим контроллерам:
// Spring автоматически регистрирует DispatcherServlet
// Для каждого запроса вызывается:
// DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)
// Когда вы делаете:
GET http://localhost:8080/api/users/123
// DispatcherServlet:
// 1. Получает запрос
// 2. Ищет подходящий Handler (контроллер + метод)
// 3. Выполняет цепочку интерцепторов
// 4. Запускает методы контроллера
// 5. Обрабатывает ответ
Архитектура обработки запроса
Полный путь запроса в Spring:
HTTP Request -> DispatcherServlet (главный сервлет) -> HandlerMapping (поиск контроллера и метода) -> Interceptors.preHandle() -> Controller method (ваш метод) -> Interceptors.postHandle() -> ViewResolver -> Interceptors.afterCompletion() -> HTTP Response
Жизненный цикл обработки в Spring
// Упрощенный код DispatcherServlet
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch(HttpServletRequest request,
HttpServletResponse response) {
try {
// 1. Поиск Handler (контроллер + метод)
HandlerExecutionChain chain = getHandler(request);
// chain содержит: controller метод + interceptors
// 2. Получение HandlerAdapter (адаптер для вызова метода)
HandlerAdapter adapter = getHandlerAdapter(chain);
// 3. Выполнить preHandle перехватчиков
for (HandlerInterceptor interceptor : chain.getInterceptors()) {
if (!interceptor.preHandle(request, response, chain.getHandler())) {
return; // Прервать обработку
}
}
// 4. Запустить метод контроллера (КЛЮЧЕВОЙ МОМЕНТ)
ModelAndView mav = adapter.handle(request, response, chain.getHandler());
// adapter вызывает через reflection ваш метод контроллера
// 5. Выполнить postHandle перехватчиков
for (HandlerInterceptor interceptor : chain.getInterceptors()) {
interceptor.postHandle(request, response, chain.getHandler(), mav);
}
// 6. Отправить ответ
render(mav, request, response);
} catch (Exception ex) {
// Обработка исключений
}
}
}
HandlerMapping — поиск контроллера
HandlerMapping определяет, какой контроллер и какой метод должны обработать запрос:
// Spring использует несколько HandlerMappings в порядке приоритета:
// 1. RequestMappingHandlerMapping (самый распространенный)
// Обрабатывает @RequestMapping, @GetMapping и т.д.
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
// Этот метод запустит DispatcherServlet
// через RequestMappingHandlerMapping
return userService.findById(id);
}
}
HandlerAdapter — вызов метода
HandlerAdapter отвечает за фактический вызов методов контроллера через reflection:
// RequestMappingHandlerAdapter (для аннотированных методов)
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter {
public ModelAndView handle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 1. Разобрать параметры из request
// 2. Преобразовать их к типам параметров метода
// 3. Вызвать метод через reflection
// 4. Преобразовать результат в ответ
return handleInternal(request, response, (HandlerMethod) handler);
}
}
Пример: как Spring запускает ваш метод
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public ResponseEntity<User> createUser(@RequestBody CreateUserRequest request) {
User user = new User(request.getName(), request.getEmail());
return ResponseEntity.status(HttpStatus.CREATED).body(user);
}
}
// Что происходит:
// 1. DispatcherServlet получает POST /api/users запрос
// 2. RequestMappingHandlerMapping находит метод createUser
// 3. RequestMappingHandlerAdapter:
// a) Читает @RequestBody
// b) Десериализует JSON в CreateUserRequest
// c) Через reflection вызывает: createUser(request)
// d) Получает результат (ResponseEntity)
// e) Сериализует ответ в JSON
// 4. DispatcherServlet возвращает HTTP 201 с телом
Важные классы Spring
Класс DispatcherServlet играет роль главного сервлета и входную точку. HandlerMapping отвечает за поиск контроллера по URL. RequestMappingHandlerMapping обрабатывает аннотации. HandlerAdapter запускает методы контроллера. RequestMappingHandlerAdapter — адаптер для аннотированных методов. HandlerInterceptor работает как перехватчики. ArgumentResolver преобразует параметры. ReturnValueHandler преобразует результат метода в ответ. HandlerExceptionResolver обрабатывает исключения.
Debugging: как увидеть процесс
// Добавь логирование Spring
// application.properties
logging.level.org.springframework.web.servlet.mvc.method.annotation=DEBUG
logging.level.org.springframework.web.servlet.DispatcherServlet=DEBUG
logging.level.org.springframework.web.servlet.mvc=DEBUG
// Или создай свой HandlerInterceptor для видимости
@Component
public class DebugInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
System.out.println("Handler: " + handler);
if (handler instanceof HandlerMethod) {
HandlerMethod method = (HandlerMethod) handler;
System.out.println("Controller: " + method.getBean().getClass().getName());
System.out.println("Method: " + method.getMethod().getName());
}
return true;
}
}
Многопоточность
Важно знать: DispatcherServlet один на все приложение, но он потокобезопасен:
// Один экземпляр DispatcherServlet обрабатывает все запросы
// Каждый запрос выполняется в отдельном потоке
// DispatcherServlet разработан для многопоточности
// Поэтому:
// - Контроллеры обычно stateless
// - Services могут быть безопасно синглтонами
// - Избегай state в контроллерах
Итог
DispatcherServlet — это класс, который запускает методы контроллеров в Spring. Он перехватывает все HTTP запросы, использует HandlerMapping для поиска контроллера, использует HandlerAdapter для вызова метода через reflection, обрабатывает перехватчики, параметры и результаты, возвращает HTTP ответ. Это фундаментальная архитектура Spring MVC, которая делает возможным управление HTTP запросами в Java приложениях.