在上一章節,筆者對SpringMVC核心源碼做了詳細分析,并提出了一個比較關鍵的問題,SpringMVC如何将用戶端的(key-value)資料和映射方法的參數進行綁定,本章通過由淺至深的方式一起和讀者了解資料綁定的相關資訊。
首先還是回到我們的執行個體:

簡單介紹下,這是上篇文章使用的案例,隻是我們添加了一個參數Integer id,然後我們在url連結上加上了?id=123,注意這個id=xxx是字元的形式,也就是說,SpringMVC将字元形式的id=123轉換成了Integer形式,下面我們就來了解SpringMVC是如何實作這種方式的。
資料綁定
首先我們看一個Demo,建立兩個類,一個存儲三個屬性,另外一個進行測試
@Controller
public class UserController {
private String name;
private Long id;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
測試類
public class MyBeanFactoryPostProcessor {
public static void main(String[] args) {
UserController userController=new UserController();
DataBinder dataBinder= new DataBinder(userController,"userController");
// 建立資料源
Map<String,String> map = new HashMap();
map.put("name","帥哥");
map.put("id","123");
map.put("age","123456");
PropertyValues propertyValues=new MutablePropertyValues(map);
dataBinder.bind(propertyValues);
System.out.println(userController);
}
}
我們先看執行結果再簡單解釋下它們的含義
通過結果我們可以看到,我們的資料源已經綁定在了我們的userController對象裡面,注意我們屬性的類型,例如id是Integer類型,我們map添加的值是字元串類型,回過來我們再看看它是怎麼實作的,實作建立一個DataBinder類,将我們的對象傳進去
然後建立了一個MutablePropertyValues,這個MutablePropertyValues其實内部有一個List用來存儲屬性
這個屬性采用 key-value的方式存放,友善擷取
然後執行dataBinder.bind(propertyValues);綁定成功,這行代碼其實做了很多事情,筆者會在下一章節詳細介紹資料綁定的底層到底做了哪些事情,這裡不做太多描述,隻簡單介紹下,我們的資料從字元型變成Integer類型,顯然需要通過資料轉換的方式将資料進行轉換,這就牽扯到另外一個重要的點-資料轉換,Spring内部有大量的内建轉換類來實作通過我們傳回的對象類型找到具體的轉換類,進而達到轉換的效果,如果沒有明白暫且不必深入研究,下個章節筆者會詳細說明,好麼我們了解了資料綁定的基本應用後接下來我們會到SpringMVC的參數綁定。
SpringMVC參數綁定源碼解析
在對資料綁定有所了解後,相信讀者應該能夠感受到SpringMVC的參數綁定過程已經有些眉目,接下來我們通過源碼的方式對參數綁定進行詳細分析,還是回到我們的SpringMVC項目,我們将代碼停在
看過前面兩章的朋友都知道這裡是反射執行我們的方法,我們繼續跟蹤
在跟蹤
再跟
再跟
在跟
最後跟蹤到這裡
然後我們看一下request的裡面有一個map
可以很清晰的看到這裡的id=123是字元串的類型通過http協定傳遞過來,再看看參數args[i]為空。
執行完這段代碼:
這裡已經将我們傳遞的字元串轉換為Integer類型并取得傳遞的值,拿到傳遞的值後我們再看
這裡會擷取我們的傳遞的值反射執行我們的方法,
好了,這裡再次回到我們所執行的方法并擷取了參數的值,現在我們回到
注意這個this.dataBinderFactory,可以看到裡面有很多的轉換器,先記住這些轉換器
我們跟進一步了解SpringMVC如何實作的,跟進去
再跟
然後一直跟蹤convertIfNecessary,直到
然後這裡的conversionService我們看下
這裡包含了非常多的轉換方式,然後進入conversionService.convert();
這裡通過我們傳遞的類型找到了我們需要到的轉換器,通過這轉換器就可以擷取我們所需要轉換的值,好了,對于SpringMVC參數綁定機制已經做了詳細分析,其實就是通過Spring内建的資料轉換機制再進行綁定,對于資料綁定、資料轉換的内容并沒有做出完整分析,我們回到convertIfNecessary方法,其實PropertyEditor也是資料轉換的實作方式之一
而PropertyEditor是來自于java.beans,那麼Spring為什麼有自己内建一個轉換器呢?筆者在下一章節詳細介紹資料綁定的源碼以及資料轉換的内容。