Spring ModelAttribute annotation uses reflection to create command object
After investigation of how spring 3 is handling command object I find out that when we have handler method like
@RequestMapping(method=RequestMethod.POST)
public String create(@ModelAttribute("account") Account account, BindingResult result) {
Spring resolves account object using following logic
if (implicitModel.containsKey(name)) {
bindObject = implicitModel.get(name);
}
else if (this.methodResolver.isSessionAttribute(name, paramType)) {
bindObject = this.sessionAttributeStore.retrieveAttribute(webRequest, name);
if (bindObject == null) {
raiseSessionRequiredException(....);
}
else {
bindObject = BeanUtils.instantiateClass(paramType);
}
So as you can see if "account" object in example is not found in implicit model nor in session then it creates command object using BeanUtils which uses reflection which is slow. And "account" obejct will be in implicit model only when we have method like following.
@开发者_开发问答ModelAttribute("account")
public Account getAccountObject() {
return new Account();
}
But generally and in example provided by spring command object is created in GET method handler as following.
@RequestMapping(method=RequestMethod.GET)
public String getCreateForm(Model model) {
model.addAttribute(new Account());
return "account/createForm";
}
So we can see that in general command object is created by reflection which is slow. What is best practice on creating command objects with annotation in spring 3.x:
It is slower, but not necessarily slow. Spring framework uses reflection extensively, especially when it works with annotations (the only way to find out that a type has annotation on it). So it is no surprise that Spring Web MVC uses reflection just like other Java web-frameworks like Struts 2 (and those which use OGNL in general) to set command object properties.
The thing is - these operations are done once per HTTP request and their time is in general neglectable. If speed is still the issue, use Apache Tapestry, which claims not to use reflection.
I recommend you stick with the way Spring proposes in its examples/tutorials (usually, it is the way that requires less code).
精彩评论