很久没来了,来mark一个,最近用spring的MVC,碰到ModelAtrribute这个标注,感觉相对其他标注比较难于理解一点,看了一遍源代码,梳理一下,做下记录。
ModelAtrribute标注本身很简单,看下他的定义:
/** * Annotation that binds a method parameter or method return value * to a named model attribute, exposed to a web view. Supported * for {@link RequestMapping} annotated handler classes. * * <p>Can be used to expose command objects to a web view, using * specific attribute names, through annotating corresponding * parameters of a {@link RequestMapping} annotated handler method). * * <p>Can also be used to expose reference data to a web view * through annotating accessor methods in a controller class which * is based on {@link RequestMapping} annotated handler methods, * with such accessor methods allowed to have any arguments that * {@link RequestMapping} supports for handler methods, returning * the model attribute value to expose. * * @author Juergen Hoeller * @since 2.5 */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ModelAttribute { /** * The name of the model attribute to bind to. * <p>The default model attribute name is inferred from the declared * attribute type (i.e. the method parameter type or method return type), * based on the non-qualified class name: * e.g. "orderAddress" for class "mypackage.OrderAddress", * or "orderAddressList" for "List<mypackage.OrderAddress>". */ String value() default ""; }
它可以标注方法(method)和参数(parameter),当标注参数时,表示从session或者impitmodel中获取这个属性对象,然后从request参数获取一些属性值来覆盖ModelAttribute标注的对象中的部分属性。
例如:
@RequestMapping public void addOrder(@ModelAttribute("order") Order order){ ..... }对应解析这段代码的地方在org.springframework.web.bind.annotation.support.HandlerMethodInvoker#resolveHandlerArguments和resolveModelAttribute中,可以仔细看下,另外你会发现,如果参数本身就是一个POJO时,其实你可以不用写ModelAttribute,它会自动根据参数类型来解析出名称并执行与有ModelAttribute标注时一样的逻辑。
Model,Map,View,String或者其他非简单对象,但不能是Long,int,Class这些类型。
对应解析代码在org.springframework.web.bind.annotation.support.HandlerMethodInvoker#invokeHandlerMethod和org.springframework.web.servlet.mvc.annotation。AnnotationMethodHandlerAdapter#getModelAndView 中。getModelAndView 主要是将执行方法后得到的结果放入到modelMap中。