Wednesday, February 1, 2012

Spring MVC 3.1 - HandlerMethod

Spring MVC 3.1 has newly introduced the concept of a HandlerMethod. HandlerMethod is a wrapper around the method which is invoked for a user web request.

For a controller with this signature,

public class AccountController {

 @RequestMapping(method = RequestMethod.GET)
 public String list(Model model) {
  model.addAttribute("accounts", this.accountManager.getAccounts());
  return "accounts/list";

 @RequestMapping(value="/new", method = RequestMethod.GET)
 public String newForm(Model model) {
  model.addAttribute(new Account());
  return "accounts/new";

a HandlerMethods map will be generated mappping the contents of the RequestMapping annotation of the method, to the HandlerMethod, something which looks like this:

path pattern: /accounts method: GET -> AccountController: list(Model)
path pattern: /accounts/new method: GET -> AccountController: newForm(Model)

Now on a user request for say for a GET on /accounts/new the appropriate HandlerMethod is retrieved from the map, and the request dispatched to the HandlerMethod.

Some of the abstractions that come into play are:
1. RequestMappingHandlerMapping - manages the map of path patterns to HandlerMethod
2. RequestMappingHandlerAdapter -  takes in a user request, transforms the request parameters into a state that is consumable by the HandlerMethod, calls the interceptors, and finally invokes the HandlerMethod

The HandlerMethod abstraction has been introduced with Spring 3.1, prior to Spring 3.1, the Handler used to be the controller class itself - when a call from a user comes in, the pattern of the request resolves upto the Controller and then a different pattern matching was performed at the level of the controller by iterating over the  Controller methods to find the right method to invoke. HandlerMethod simplifies the flow significantly by recognizing that a request mapped method is the actual handler and not the controller itself ( this is functional in a way - by making the Controller method a first class citizen).

This change from 3.0.x to 3.1.0 is significant, what I have truly appreciated about the Spring codebase is that this change is transparent to the developers - as long as the Spring MVC defaults are adhered to (using mvc:annotation-driven etc), this change of engine under the covers, just works.

No comments:

Post a Comment