Reputation: 105
Let's say I have a class annotated with @Controller and the respective mappings for the instance method like this.
@Controller
@ResponseBody
public class UserController {
@GetMapping("/example")
public User fetchUserExample() {
// ...
}
}
Also, let's say there are a 1000 controllers like above with different URL mappings. I invoked say any of the URL and the respective controller is found and the respective method is called and response is returned.
But what I am confused about is how exactly dispatcherServlet knows where it'd find the method for the requested URL? Does it scans through each and every controller classes one by one looking for a match and does it do this for every request? If so, it doesn't really seem to be an effective approach.
I know we can annotate the class as well but that still doesn't answer the question as it'd still need to scan the classes for a match.
I was hoping it'd be maintaining some kind of track about the controllers and their respective mappings.
I googled a lot for this but almost wherever I went only skimmed through the surface that the annotations such as @GetMapping, @RequestMapping
tell it about the method to call. But we know that. How does dispatcherServlet pinpoints the class in the first place or does it follow the approach that I wrote above?
Some sites mentioned things like HandlerMapping, SimpleControllerHandlerAdapter, RequestMappingHandlerAdapter
but since I am new to Spring these things don't make sense to me as to how they come in picture here.
Any input would be appreciated.
Upvotes: 2
Views: 1566
Reputation: 90557
As the mapping annotations are static and never be changed during runtimes, it does not need to scan every controller class to find the matched method whenever it process a request. Just scan it once at the application start and store the scanning result to a kind of map . So finding which method to be invoked for a request is just a matter of looking up some data from this map which should be very effective.
If you are interested in the actual codes , look at RequestMappingHandlerMapping#lookupHandlerMethod()
for the logic of finding which method to be invoked for a request. The scanning results are stored to an internal MappingRegistry
which lookupHandlerMethod()
will get the data from it for finding the matched method.
You can also try to grab a RequestMappingHandlerMapping
bean , get the mapping of MappingRegistry
by :
RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
Map<RequestMappingInfo, HandlerMethod> handlerMethodMapping = mapping.getHandlerMethods();
handlerMethodMapping.forEach((k,v)->{
System.out.println(k);
System.out.println(v);
System.out.println("-----");
});
which will print out which URL request is mapped to which handler method.
Upvotes: 3