眾所周知,Strut 2的Action類通過屬性可以獲得所有相關的值,如請求參數(shù)、Action 配置參數(shù)、向其他Action傳遞屬性值(通過chain結果)等等。要獲得這些參數(shù)值,我 們要做的唯一一件事就是在Action類中聲明與參數(shù)同名的屬性,在Struts 2調用Action 類的Action方法(默認是execute方法)之前,就會為相應的Action屬性賦值。 要完成這個功能,有很大程度上,Struts 2要依賴于ValueStack對象。這個對象貫 穿整個Action的生命周期(每個Action類的對象實例會擁有一個ValueStack對象)。當 Struts 2接收到一個.action的請求后,會先建立Action類的對象實例,但并不會調用 Action方法,而是先將Action類的相應屬性放到ValueStack對象的頂層節(jié)點 (ValueStack對象相當于一個棧)。只是所有的屬性值都是默認的值,如String類型的 屬性值為null,int類型的屬性值為0等。 在處理完上述工作后,Struts 2就會調用攔截器鏈中的攔截器,當調用完所有的攔 截器后,最后會調用Action類的Action方法,在調用Action方法之前,會將ValueStack 對象頂層節(jié)點中的屬性值賦給Action類中相應的屬性。大家要注意,在這里就給我們帶 來了很大的靈活性。也就是說,在Struts 2調用攔截器的過程中,可以改變ValueStack 對象中屬性的值,當改變某個屬性值后,Action類的相應屬性值就會變成在攔截器中最 后改變該屬性的這個值。 從上面的描述很容易知道,在Struts 2的的Action類可以獲得與屬性同名的參數(shù)值 就是通過不同的攔截器來處理的,如獲得請求參數(shù)的攔截器是params,獲得Action的配 置參數(shù)的攔截器是staticParams等。在這些攔截器內部讀取相應的值,并更新 ValueStack對象頂層節(jié)點的相應屬性的值。而ValueStack對象就象一個傳送帶,將屬性 值從一個攔截器傳到了另一個攔截器(當然,在這其間,屬性值可能改變),最后會傳 到Action對象,并將ValueStack對象中的屬性的值終值賦給Action類的相應屬性
甚是不解,求助于網(wǎng)上依然沒有得到解決! 花了點時間看了下源碼! 發(fā)現(xiàn): struts2 參數(shù)攔載器在注入值的時候,有兩種機制,(調用ognl) 這是OgnlRuntime 類中一段源碼 hasSetMethod( context, target, targetClass, name ) || hasField( context, target, targetClass, name ); 他會先查看你的action 中有沒有對應的方法,如果發(fā)現(xiàn)無此方法,他會利用第二種方法 直接給屬性覆值,而無需對應的set方法!(當然都是通過反射機制實現(xiàn)的) 如果action 中屬性過多的話,我覺得就不用寫set get 方法了!(不知道這個會不會給以 后維護帶來問題).
個人總結:OGNL中的值棧相當于一個數(shù)據(jù)的中轉站,或者叫數(shù)據(jù)的緩沖存儲中心。另外,OGNL除了有值棧(VS)這個特別的對象外,它的表達式語言也自成一派。 |
|