Контроллеры + методы и URL-адреса изначально отображаются во время запуска или они повторяются каждый раз для запроса?
При реализации по умолчанию HandlerMapping
отображение URL-адресов контроллеров Spring выполняется при запуске.Это не имело бы смысла делать это при каждом вызове запроса, поскольку отображение URL не может измениться после запуска контейнера.
Помимо этого вопроса, рассматривайте контроллеры как bean-компоненты, и они устанавливаются / инициализируются Spring один раз: при запуске контейнера,Так что рассмотрите аннотацию уровня класса для @RequestMapping
просто как ярлык, который будет сухим.
Вот код, который должен вас заинтересовать: AbstractUrlHandlerMapping.getHandlerInternal()
используется под капотом реализацией по умолчанию HandlerMapping
:
@Override
@Nullable
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = obtainApplicationContext().getBean(handlerName);
}
validateHandler(rawHandler, request);
handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
}
}
if (handler != null && logger.isDebugEnabled()) {
logger.debug("Mapping [" + lookupPath + "] to " + handler);
}
else if (handler == null && logger.isTraceEnabled()) {
logger.trace("No handler mapping found for [" + lookupPath + "]");
}
return handler;
}
Интересно то, что обработчик создаетсяодин раз за всю жизнь компонента:
if (handler == null) {
// init handler...
}
return handler;
Обратите внимание, что интерфейс HandlerMapping
, определяющий getHandler()
, указывает, что вы можете создать собственную логику для разрешения отображения:
Интерфейс, который будет реализован объектами, которые определяют отображение между запросами и объектами-обработчиками.Этот класс может быть реализован разработчиками приложений, хотя в этом нет необходимости, поскольку BeanNameUrlHandlerMapping и RequestMappingHandlerMapping включены в платформу.Первый используется по умолчанию, если в контексте приложения не зарегистрирован ни один компонент HandlerMapping.Реализации HandlerMapping могут поддерживать отображаемые перехватчики, но не обязаны.
Таким образом, не кеширование отображений URL вполне возможно при создании собственной реализации отображения обработчика, но это, конечно, не поведение реализации по умолчанию по справедливым причинам.