天天看點

SpringMVC參數綁定機制

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

首先還是回到我們的執行個體:

SpringMVC參數綁定機制
SpringMVC參數綁定機制

簡單介紹下,這是上篇文章使用的案例,隻是我們添加了一個參數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);
    }
​
}
           

我們先看執行結果再簡單解釋下它們的含義

SpringMVC參數綁定機制

通過結果我們可以看到,我們的資料源已經綁定在了我們的userController對象裡面,注意我們屬性的類型,例如id是Integer類型,我們map添加的值是字元串類型,回過來我們再看看它是怎麼實作的,實作建立一個DataBinder類,将我們的對象傳進去

SpringMVC參數綁定機制

然後建立了一個MutablePropertyValues,這個MutablePropertyValues其實内部有一個List用來存儲屬性

SpringMVC參數綁定機制

這個屬性采用 key-value的方式存放,友善擷取

SpringMVC參數綁定機制

然後執行dataBinder.bind(propertyValues);綁定成功,這行代碼其實做了很多事情,筆者會在下一章節詳細介紹資料綁定的底層到底做了哪些事情,這裡不做太多描述,隻簡單介紹下,我們的資料從字元型變成Integer類型,顯然需要通過資料轉換的方式将資料進行轉換,這就牽扯到另外一個重要的點-資料轉換,Spring内部有大量的内建轉換類來實作通過我們傳回的對象類型找到具體的轉換類,進而達到轉換的效果,如果沒有明白暫且不必深入研究,下個章節筆者會詳細說明,好麼我們了解了資料綁定的基本應用後接下來我們會到SpringMVC的參數綁定。

SpringMVC參數綁定源碼解析

在對資料綁定有所了解後,相信讀者應該能夠感受到SpringMVC的參數綁定過程已經有些眉目,接下來我們通過源碼的方式對參數綁定進行詳細分析,還是回到我們的SpringMVC項目,我們将代碼停在

SpringMVC參數綁定機制

看過前面兩章的朋友都知道這裡是反射執行我們的方法,我們繼續跟蹤

SpringMVC參數綁定機制

在跟蹤

SpringMVC參數綁定機制

再跟

SpringMVC參數綁定機制

再跟

SpringMVC參數綁定機制

在跟

SpringMVC參數綁定機制

最後跟蹤到這裡

SpringMVC參數綁定機制

然後我們看一下request的裡面有一個map

SpringMVC參數綁定機制

可以很清晰的看到這裡的id=123是字元串的類型通過http協定傳遞過來,再看看參數args[i]為空。

SpringMVC參數綁定機制

執行完這段代碼:

SpringMVC參數綁定機制

這裡已經将我們傳遞的字元串轉換為Integer類型并取得傳遞的值,拿到傳遞的值後我們再看

SpringMVC參數綁定機制

這裡會擷取我們的傳遞的值反射執行我們的方法,

SpringMVC參數綁定機制

好了,這裡再次回到我們所執行的方法并擷取了參數的值,現在我們回到

SpringMVC參數綁定機制

注意這個this.dataBinderFactory,可以看到裡面有很多的轉換器,先記住這些轉換器

SpringMVC參數綁定機制

我們跟進一步了解SpringMVC如何實作的,跟進去

SpringMVC參數綁定機制

再跟

SpringMVC參數綁定機制

然後一直跟蹤convertIfNecessary,直到

SpringMVC參數綁定機制

然後這裡的conversionService我們看下

SpringMVC參數綁定機制

這裡包含了非常多的轉換方式,然後進入conversionService.convert();

SpringMVC參數綁定機制

這裡通過我們傳遞的類型找到了我們需要到的轉換器,通過這轉換器就可以擷取我們所需要轉換的值,好了,對于SpringMVC參數綁定機制已經做了詳細分析,其實就是通過Spring内建的資料轉換機制再進行綁定,對于資料綁定、資料轉換的内容并沒有做出完整分析,我們回到convertIfNecessary方法,其實PropertyEditor也是資料轉換的實作方式之一

SpringMVC參數綁定機制

而PropertyEditor是來自于java.beans,那麼Spring為什麼有自己内建一個轉換器呢?筆者在下一章節詳細介紹資料綁定的源碼以及資料轉換的内容。