SSH Struts2內(nèi)部是如何工作的

2018-09-28 18:56 更新

Struts2 內(nèi)部是如何工作的

前面說(shuō)完了Spring、Hibernate,很自然今天輪到struts了。struts的核心原理就是通過(guò)攔截器來(lái)處理客戶(hù)端的請(qǐng)求,經(jīng)過(guò)攔截器一系列的處理后,再交給Action。下面先看看struts官方的工作原理圖:



圖1 struts原理圖

簡(jiǎn)單分析一下:首先客戶(hù)端發(fā)來(lái)HttpServletRequest請(qǐng)求,傳遞給FilerDispatcher(ActionMapper是訪問(wèn)靜態(tài)資源(struts的jar文件等)時(shí)用的,平時(shí)很少用),然后FilerDispatcher會(huì)為我們創(chuàng)建一個(gè)ActionProxy,ActionProxy會(huì)通過(guò)ConfigurationManager獲得struts.xml文件中的信息,ActionProxy擁有一個(gè)ActionInvocation實(shí)例,通過(guò)調(diào)用ActionInvocation的invoke()方法,來(lái)挨個(gè)處理Interceptor,最后處理Action,接著Result返回,再逆序經(jīng)過(guò)Interceptor,最后得到HttpServletResponse返回給客戶(hù)端。

如果不太明白呢,那就看看下面這張時(shí)序圖,也許你就懂了:


圖2 struts原理時(shí)序圖

上面的時(shí)序圖邏輯就比較清晰了,我就不過(guò)多解釋了??赐阺truts的原理圖,我們還是需要通過(guò)代碼來(lái)進(jìn)一步了解它具體是怎么實(shí)現(xiàn)的。首先,我們需要一個(gè)ActionInvocation:

package com.tgb.struts;  
import java.util.ArrayList;  
import java.util.List;  

public class ActionInvocation {  
    List<Interceptor> interceptors = new ArrayList<Interceptor>();  
    int index = -1;  
    Action a = new Action();  

    public ActionInvocation() {  
        this.interceptors.add(new FirstInterceptor());  
        this.interceptors.add(new SecondInterceptor());       
    }  

    public void invoke() {  
        index ++;  
        if(index >= this.interceptors.size()) {  
            a.execute();  
        }else {  

            this.interceptors.get(index).intercept(this);  
        }  
    }  
}  

我們實(shí)現(xiàn)的ActionInvocation是將Interceptor寫(xiě)在里面的,但實(shí)際上是通過(guò)反射加載的,原理同之前寫(xiě)的Spring與Hibernate的博客,相同的代碼就不在這里占用篇幅了,也沒(méi)啥意思。不知道怎么實(shí)現(xiàn)的朋友請(qǐng)查看前面幾篇博客。

接下來(lái)是我們的Interceptor接口以及兩個(gè)簡(jiǎn)單的實(shí)現(xiàn):

package com.tgb.struts;  

public interface Interceptor {  
    public void intercept(ActionInvocation invocation) ;  
}  

package com.tgb.struts;  

public class FirstInterceptor implements Interceptor {  

    public void intercept(ActionInvocation invocation) {  
        System.out.println("FirstInterceptor Begin...");  
        invocation.invoke();  
        System.out.println("FirstInterceptor End...");  
    }  

}  

package com.tgb.struts;  

public class SecondInterceptor implements Interceptor {  

    public void intercept(ActionInvocation invocation) {  
        System.out.println("SecondInterceptor Begin...");  
        invocation.invoke();  
        System.out.println("SecondInterceptor End...");  
    }  

}  

然后就是我們的Action:

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
package com.tgb.struts;  

public class Action {  
    public void execute() {  
        System.out.println("Action Run...");  
    }  
}  

最后是我們的客戶(hù)端調(diào)用:

package com.tgb.struts;  

public class Client {  
    public static void main(String[] args) {  
        new ActionInvocation().invoke();  
    }  
}  

差點(diǎn)忘了,還有我們最后的執(zhí)行結(jié)果:

FirstInterceptor Begin...  
SecondInterceptor Begin...  
Action Run...  
SecondInterceptor End...  
FirstInterceptor End...  

通過(guò)上面的執(zhí)行結(jié)果,我們可以很清楚的看到,請(qǐng)求來(lái)的時(shí)候會(huì)按照順序被所有配置的攔截器攔截一遍,然后返回的時(shí)候會(huì)按照逆序再被攔截器攔截一遍。這跟數(shù)據(jù)結(jié)構(gòu)中的“?!狈浅n?lèi)似(FIFO-先進(jìn)先出),數(shù)據(jù)結(jié)構(gòu)我不太懂,也許這樣比喻有些不妥。各位根據(jù)自己的認(rèn)識(shí)理解吧。

最近一直在研究這三大框架,折騰半天它們都離不開(kāi)集合,離不開(kāi)反射。其實(shí)它們道理都是想通的,搞懂一個(gè),其他的也就很好懂了。等著吧,早晚咱們自己寫(xiě)一個(gè)更好用的。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)