Invoke global, then local @InitBinder/@ModelAttribute

@InitBinder and @ModelAttribute methods in @ControllerAdvice classes
are now invoked first, allowing any such methods in the @Controller
class to override them.

Issue: SPR-10419
master
Rossen Stoyanchev 12 years ago
parent 640555194b
commit 78fcd28389
  1. 18
      spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapter.java
  2. 11
      spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerAdapterTests.java

@ -772,16 +772,17 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
this.modelAttributeCache.put(handlerType, methods);
}
List<InvocableHandlerMethod> attrMethods = new ArrayList<InvocableHandlerMethod>();
for (Method method : methods) {
Object bean = handlerMethod.getBean();
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
// Global methods first
for (Entry<ControllerAdviceBean, Set<Method>> entry : this.modelAttributeAdviceCache.entrySet()) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
}
for (Method method : methods) {
Object bean = handlerMethod.getBean();
attrMethods.add(createModelAttributeMethod(binderFactory, bean, method));
}
return new ModelFactory(attrMethods, binderFactory, sessionAttrHandler);
}
@ -801,16 +802,17 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
this.initBinderCache.put(handlerType, methods);
}
List<InvocableHandlerMethod> initBinderMethods = new ArrayList<InvocableHandlerMethod>();
for (Method method : methods) {
Object bean = handlerMethod.getBean();
initBinderMethods.add(createInitBinderMethod(bean, method));
}
// Global methods first
for (Entry<ControllerAdviceBean, Set<Method>> entry : this.initBinderAdviceCache .entrySet()) {
Object bean = entry.getKey().resolveBean();
for (Method method : entry.getValue()) {
initBinderMethods.add(createInitBinderMethod(bean, method));
}
}
for (Method method : methods) {
Object bean = handlerMethod.getBean();
initBinderMethods.add(createInitBinderMethod(bean, method));
}
return createDataBinderFactory(initBinderMethods);
}

@ -181,7 +181,8 @@ public class RequestMappingHandlerAdapterTests {
this.handlerAdapter.afterPropertiesSet();
ModelAndView mav = this.handlerAdapter.handle(this.request, this.response, handlerMethod);
assertEquals("globalAttrValue", mav.getModel().get("globalAttr"));
assertEquals("lAttr1", mav.getModel().get("attr1"));
assertEquals("gAttr2", mav.getModel().get("attr2"));
}
@ -200,6 +201,11 @@ public class RequestMappingHandlerAdapterTests {
@SuppressWarnings("unused")
private static class SimpleController {
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("attr1", "lAttr1");
}
public String handle() {
return null;
}
@ -227,7 +233,8 @@ public class RequestMappingHandlerAdapterTests {
@ModelAttribute
public void addAttributes(Model model) {
model.addAttribute("globalAttr", "globalAttrValue");
model.addAttribute("attr1", "gAttr1");
model.addAttribute("attr2", "gAttr2");
}
}

Loading…
Cancel
Save