程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> how tomcat works 讀書筆記 十一 StandWrapper 下

how tomcat works 讀書筆記 十一 StandWrapper 下

編輯:C++入門知識

how tomcat works 讀書筆記 十一 StandWrapper 下


StandardWrapperValve

StandardWrapperValve是StandardWrapper的基礎閥,主要完成了三個工作。
1 調用StandardWrapper的allocate的方法來獲得該StandardWrapper所表示的servlet實例
2 執行與該servelt相關聯的全部過濾器
3 調用servlet的service方法

其中第二三步可以細分為
調用它的 private createFilterChain 方法獲得過濾鏈
調用過濾器鏈的 doFilter 方法。這裡面就調用了servlet 的 service方法
釋放過濾器鏈
調用包裝器的deallocate方法

如果Servlet無法使用了,調用包裝器的 unload 方法


我們看看大致的代碼片段
// Allocate a servlet instance to process this request
try {
    if (!unavailable) {
    servlet = wrapper.allocate();
    }
}
...
// Acknowlege the request
try {
    response.sendAcknowledgement();
}
...
// Create the filter chain for this request
    ApplicationFilterChain filterChain = createFilterChain(request,servlet);
// Call the filter chain for this request// This also calls the servlet's servicet() method
try {
    String jspFile = wrapper.getJspFile();
    if (jspFile != null)
    sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
    else
    sreq.removeAttribute(Globals.JSP_FILE_ATTR);
    if ((servlet != null) && (filterChain != null)) {
    filterChain.doFilter(sreq, sres);
    }
    sreq.removeAttribute(Globals.JSP_FILE_ATTR);
}
...
// Release the filter chain (if any) for this request
try {
    if (filterChain != null)
        filterChain.release();
}
...
// Deallocate the allocated servlet instance
try {
    if (servlet != null) {
        wrapper.deallocate(servlet);
    }
}
...
// If this servlet has been marked permanently unavailable,
// unload it and release this instance
try {
    if ((servlet != null) && (wrapper.getAvailable() ==Long.MAX_VALUE)) {
        wrapper.unload();
    }
}


看了上面的代碼,大家應該能看出來最復雜的部分有兩處
其一 ApplicationFilterChain filterChain = createFilterChain(request,servlet);
其二 filterChain.doFilter(sreq, sres);
一步一步來。

FilterDef類

這個類的全名應該是FilterDefinition,過濾器描述類。
裡面包含了一個Filter的filterClass,filterName等基本信息,及get/set方法。
這裡面的屬性,我們可以看看這個
    /**
     * The set of initialization parameters for this filter, keyed by
     * parameter name.
     */
    private Map parameters = new HashMap();
用HashMap存儲了初始化參數,它有get方法,增加屬性的方法是addInitParameter(String name, String value)。

ApplicationFilterConfig類

org.apache.catalina.core.ApplicationFilterConfig 實現了javax.servlet.FilterConfig 接口。ApplicationFilterConfig 負責管理 web應用程序啟動的時候創建的過濾器實例。
其構造函數如下:
public ApplicationFilterConfig(Context context, FilterDef filterDef)
throws ClassCastException, ClassNotFoundException,IllegalAccessException, InstantiationException, ServletException
在這裡我們主要談談它的getFilter方法,該方法的功能其實就是加載過濾器類並初始化它。
首先從filterDef裡面獲得filterClass;
        String filterClass = filterDef.getFilterClass();
        ClassLoader classLoader = null;
        if (filterClass.startsWith("org.apache.catalina."))
            classLoader = this.getClass().getClassLoader();
        else
            classLoader = context.getLoader().getClassLoader();
    .....
            Class clazz = classLoader.loadClass(filterClass);
        this.filter = (Filter) clazz.newInstance();
        filter.init(this);
        return (this.filter);
還是沒有什麼要說的。


ApplicationFilterChain類

StandardWrapperValve 類中的 invoke 方法創建一個該類的實例並且調用它的 doFilter 方法。ApplicationFilterChain類的doFilter(其實是internalDoFilter)調用該鏈中第一個過濾器的 doFilter 方法。
ApplicationFilterChain類中,有一個ApplicationFilterConfig的引用

private ArrayList filters = new ArrayList();

看到了把,數組形式來存放鏈條。

典型的責任鏈模式。

Filter 接口中doFilter 方法的簽名如下:
public void doFilter(ServletRaquest request, ServletResponse response,FilterChain chain)
            throws java.io.IOException, ServletException
在ApplicationFilterChain的doFilter方法中,它會將自己作為第三個參數傳遞給它。
我們看一個Filter實現類的例子
public void doFilter(ServletRequest request, ServletResponse response,
                    FilterChain chain) throws IOException, ServletException {
    // do something here
    ...
    chain.doFilter(request, response);
}
循環往復了
此處的循環不是那麼容易理解,建議參考鄙人的另一篇博客

http://blog.csdn.net/dlf123321/article/details/40078583


等所有的Filter都執行完了,就是下面的代碼

           if ((request instanceof HttpServletRequest) &&
                (response instanceof HttpServletResponse)) {
                servlet.service((HttpServletRequest) request,
                                (HttpServletResponse) response);
            } else {
                servlet.service(request, response);
            }

什麼時候Filter才算執行完了呢?

 private Iterator iterator = null;

....

 if (this.iterator == null)
            this.iterator = filters.iterator();

        // Call the next filter if there is one
        if (this.iterator.hasNext()) {

                    //執行filter

       }
...
      //調用servlet的service的代碼塊
...


應用程序

和之前的幾章沒有什麼區別,不再贅述。






  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved