Как параметры методов обработчика Spring MVC @Controller автоматически разрешаются во время выполнения?

Как DispatcherServlet (или любой другой компонент, поддерживающий инфраструктуру Spring MVC) динамически разрешает сигнатуру метода обработчика экземпляра @Component и как он узнает, какие параметры/типы ожидаются, в каком порядке, в этом методе ?

Если у меня есть метод обработчика @RequestMappinged, в моем экземпляре @Controller определяется любая версия его подписи:

public String f() {...}

public String f(Model model) {...}

public String f(HttpServletRequest, Model model) {...}

public String f(Model model, HttpServletRequest) {...}

public String f(SomeEntity se, Model model, HttpServletRequest, AnotherModel am) {...}

//so on..

будет работать нормально, независимо от количества, типов и порядка параметров, которые, в конце концов, снабжены соответствующими аргументами, опять же не учитывая их количества, порядка и типов.

Должна быть проделана большая работа, чтобы правильно создать экземпляр ожидаемых аргументов, передать их в правильном порядке, возможно, даже выполнить некоторое приведение типов, если это необходимо... и так далее, но я не понять основы этого.

Я просмотрел соответствующие источники из модуля spring-webmvc и источники модуля DispatcherServlet; однако, не получил твердого понимания основного механизма.

Я могу предположить, что могут быть задействованы какие-то BeanPostProcessor.. выполнение рефлексивного доступа и т. д.. но даже в этом случае, поскольку я не уверен в том, что происходит, я был бы очень признателен за любой ценный вклад.


person Giorgi Tsiklauri    schedule 20.01.2021    source источник


Ответы (2)


В Spring MVC есть три реализации HandlerMapping: BeanNameUrlHandlerMapping, SimpleUrlHandlerMapping и ControllerClassNameHandlerMapping. Подробнее об этом можно прочитать здесь: https://www.baeldung.com/spring-handler-mappings

person Ionathan Ardelean    schedule 20.01.2021
comment
Я думаю, что это не ответ на мой вопрос. - person Giorgi Tsiklauri; 20.01.2021

Я не использовал Spring годами, но этот пост дает довольно хорошее пошаговое описание жизненного цикла запроса Spring MVC

Когда DispatcherServlet получает запрос, он выполняет итерацию по этому списку, пока не найдет соответствующий объект-обработчик для рассматриваемого запроса. Для простоты рассмотрим только RequestMappingHandlerMapping.

Бин этого типа хранит сопоставление аннотированных методов @RequestMapping (фактический объект Method, полученный с помощью отражения), хранящихся как экземпляры HandlerMethod и заключенных в объекты RequestMappingInfo, которые содержат данные сопоставления для сопоставления с запросом, т.е. URL, заголовки и параметры запроса.

DispatcherServlet извлекает наиболее подходящий HandlerMethod из этих и любых соответствующих экземпляров HandlerInterceptor, которые вы могли зарегистрировать. Он извлекает их как объект HandlerExecutionChain. Сначала он применит любую предварительную обработку с помощью HandlerInterceptors. Затем он попытается вызвать ваш метод HandlerMethod. Обычно (но не всегда) это аннотированный метод @RequestMapping внутри аннотированного класса @Controller. Это производит то, что Spring называет результатом отправки. Затем DispatcherServlet применяет пост-обработку с помощью HandlerInterceptors.

person Lactose.Int.Robot    schedule 20.01.2021