Ezio Auditore
Ezio Auditore

Reputation: 105

How does DispatcherServlet exactly figures out which controller to call?

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

Answers (1)

Ken Chan
Ken Chan

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

Related Questions