前一章寫struts設定檔的解析感覺有點太細了,且由於筆頭功夫稍欠火候,感覺寫得不夠徹底。這章從宏觀上對解析做個總結,希望能夠先從整體上熟悉它。
之前也提到,ActionServlet在解析設定檔時是按照模組來進行的,對每個模組都會有一個ModuleConfig對象。這個對象是非常重要的,struts中的配置資訊都可以從中獲得,而且在之後處理使用者請求時有很大的用武之地。ModuleConfig其實是一個介面,在Struts1中有一個預設的實作類別ModuleConfigImpl。當然,我們在配置servlet時,可以通過指定初始化參數configFactory,提供一個自訂的ModuleConfigFactory來產生ModuleConfig對象。如果沒有指定初始化參數,則預設使用ModuleConfigImpl。
該介面的類圖(列出了主要的幾個方法)如下:
在對struts設定檔解析的過程中,每次對一個標籤解析完畢後,則會把對應的Config對象加入到ModuleConfig對象中,具體調用的就是這些方法。這些操作也都是在SetNextRule對象中完成的。查看SetNextRule的源碼就可以知道,該類的實際操作都是在end()方法裡完成的,也就是說,在對某個標籤解析結束時,才會調用。
當然,對於一個標籤可能會配置多個,比如<action>。對於設定檔中的每個<action>,實際上都有一個AcionConfig對象與之對應,然後通過調用addActionConfig(),將該對象放在ModuleConfig對象的一個Map裡。該Map會以Action的path為key,以ActionConfig對象作為值。
上面說的是將這些config對象添加到ModuleConfig對象中,至於這些config對象是如何產生,以及config對象的屬性是如何設定的,實際上都是Digester的功勞了,上一章比較詳細的說過了。這裡再從處理的流程上提一下,以便有個宏觀印象。
Digester在解析標籤時,有兩個方法不得不提:
1、startElement:解析標籤開始時的處理;
2、endElement:解析標籤結束時的處理。
實際上這兩個方法在處理時,都是調用與當前標籤相對應的Rule對象進行處理。第二章中有提到將元素與規則進行映射,實際上就是這裡用到了。Rule類圖如下:
在startElement()方法中,會調用Rule的begin()方法。在endElement()方法中會調用Rule的body()和end()方法。Rule的子類會選擇性的重寫這三個方法,Rule類中這三個方法都是空的,也就是不做任何處理。
以FactoryCreateRule類為例(<action>標籤會用到),begin()方法根據工廠對象建立一個對象(<action>標籤對應的工廠類為ActionMappingFactory),並將這個對象放入Digester對象的棧中。end()方法將建立的對象從棧中彈出。
希望這次寫得明白些。。。