Are controllers+methods and urls are mapped initially during startup
or they are iterated everytime for a request?
With default HandlerMapping
implementation, Url mappings of Spring controllers are done at startup. That would make no sense to do that at each request invocation since the url mapping cannot change once the container was started.
Beyond this question, consider Controllers as beans and these are set/initialized by Spring a single time : at container startup.
So consider the class level annotation for @RequestMapping
simply as a shortcut to be dry.
Here is a code that should interest you : AbstractUrlHandlerMapping.getHandlerInternal()
used under the hood by the default implementation of HandlerMapping
:
@Override
@Nullable
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
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;
}
The interesting part is that the handler is created a single time in the whole life of the bean :
if (handler == null) {
// init handler...
}
return handler;
Note that the HandlerMapping
interface that defines getHandler()
specifies that you could create your own logic for the mapping resolution :
Interface to be implemented by objects that define a mapping between
requests and handler objects. This class can be implemented by
application developers, although this is not necessary, as
BeanNameUrlHandlerMapping and RequestMappingHandlerMapping are
included in the framework. The former is the default if no
HandlerMapping bean is registered in the application context.
HandlerMapping implementations can support mapped interceptors but do
not have to.
So not caching url mappings is fairly possible by creating your own implementation of handler mapping , but that is of course not the behavior of the default implementation for fair reasons.