SpringMVC 4.0 @ModelAttribute 註解(附源碼分析流程)

@Controller
public class Hello {

    /**
     * 該標記可以在調用其他函數的時候 先運行
     * @ModelAttribute註解也可以用來修飾目標方法的POJO的入參,其屬性值有如下作用:
     * 1>SpringMVC會使用value屬性值在implicitModel中查找對應的對象,若存在則會直接傳入到目標方法的入參中
     * 2>SrpingMVC會value爲key,POJO的類型作爲value,存入到request中
     * @param id
     * @param map
     */
    @ModelAttribute
    public void getUser(@RequestParam(value="id",required=false) Integer id,
        Map<String, Object> map){
        if(null != id)
        {
            User user = new User();
            map.put("user", user);
        }
    }

    /**
     * @ModelAttribute 註解執行流程
     * 1.執行@ModelAttribute直接修飾的方法 springmvc 識別了方法裏面的map參數
     * 2.SpringMVC 從map中取出了User對象,並把表單的請求參數賦給User對象的對應屬性
     * 3.SpringMVC 把上述對象傳入目標的參數 也就是帶有User 的對應請求的方法中去 這樣不用重新創建一個新的對象
     * 
     * @param user
     * @param request
     * @param response
     * @return forward
     */
    @RequestMapping("/pojo")
    public String pojo(User user, HttpServletRequest request,
            HttpServletResponse response) {

        request.setAttribute("user", user);
        System.out.println("pojo" + user);
        return "pojo";
    }

}

表單

    <form action="pojo">
        username:<input type="text" name="username"></input><br/>
        <!--password:<input type="password" name="password"></input><br/>  -->
        phone:<input type="hidden" name="phone" value="123456"></input><br/>
        city:<input type="text" name="address.city"></input><br/>
        province:<input type="text" name="address.province"></input><br/><br/>
        <input type="submit" name="提交"/>        
    </form>

源碼分析(反正也沒人來看這裏的分析)

一.調用@ModdelAttribute 註解修飾的方法,實際上把@ModdelAttribute方法中Map的數據放入到implictiModel中

二.解析請求處理器的目標參數,實際上該目標參數來自於,WebDataBinder對象的target屬性

1.創建WebDataBinder對象 :

1>.確定objectName屬性:若傳入的attrName 屬性值爲空串“”,則objectName爲類名第一
個字母小寫,注意:attrName 若目標方法的POJO屬性使用了@ModelAttribute來修飾,則
attrName 值即爲@ModelAttribute的value屬性值
2>.確定traget屬性:在implicitModel中查找attrName對應的值,若存在可獲取,若不存
在:驗證當前Handler是否使用了@SessionAttribute 進行修飾,若使用了,則嘗試從
Session中獲取attrName所對應的屬性,若session中沒有對應的屬性值則會拋出異常。若
Handler沒有使用@SessionAttributes進行修飾,或@SessionAttributes中沒有使用
value值指定key和attrName相匹配,則通過反射創建了POJO對象

2.SpringMVC把表單的請求賦值給了WebDataBinder的target對應屬性。

3.SpringMVC會把WebDataBinder的attrName和target給到implicitModel

4.把WebDataBinder的target作爲參數傳遞給目標方法的入參

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章