1. 程式人生 > >Servlet的配置引數load-on-startup引數理解

Servlet的配置引數load-on-startup引數理解

當我們配置Servlet時,我們可以看到一個引數 load-on-startup,那麼他具體的作用是什麼呢?我們來看一下英語的介紹。

<servlet>

    <servlet-name>Dispatch</servlet-name>
    <servlet-class>com.linjiang.Dispatch</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SessionTest</servlet-name>
    <url-pattern>/SessionTest</url-pattern>

  </servlet-mapping>

英語介紹:

Servlet specification:
The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses.   If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.


翻譯意思大概如下:
1)load-on-startup 元素標記容器是否應該在啟動的時候載入這個servlet,(例項化並呼叫其init()方法)。

2)它的值必須是一個整數,表示servlet應該被載入的順序

3)如果該元素不存在或者這個數為負時,則容器會當該Servlet被請求時,再載入。

4)當值為0或者大於0時,表示容器在應用啟動時就載入並初始化這個servlet;

5)正數的值越小,該servlet的優先順序越高,應用啟動時就越先載入。

6)當值相同時,容器就會自己選擇順序來載入。(當然我寫了幾個測試程式,沒有抓住它的規律性,我們暫且理解為容器自主選擇!)

所以,<load-on-startup>x</load-on-startup>,中x的整數取值代表的初始化的載入的先後順序。

思考一: 假如<load-on-startup></load-on-startup>、<load-on-startup>2.4</load-on-startup>、

<load-on-startup>-2.4</load-on-startup>、<load-on-startup>張三</load-on-startup>

<load-on-startup></load-on-startup>時,Web.xml不報錯,而正浮點數和負浮點數以及字串時Web.xml都會報錯,但專案仍可以執行,Servlet仍然在專案執行後直接被初始化。那麼我們去參考一下它原始碼是如何實現載入Servlet的

for (ServletDef servlet : servlets.values()) { 
            Wrapper wrapper = context.createWrapper(); 
            String jspFile = servlet.getJspFile(); 
            if (jspFile != null) { 
                wrapper.setJspFile(jspFile); 
            } 
            if (servlet.getLoadOnStartup() != null) { 
                wrapper.setLoadOnStartup(servlet.getLoadOnStartup().intValue()); 
            } 
            if (servlet.getEnabled() != null) { 
                wrapper.setEnabled(servlet.getEnabled().booleanValue()); 
            } 
            wrapper.setName(servlet.getServletName()); 
            Map<String,String> params = servlet.getParameterMap(); 
            for (Entry<String, String> entry : params.entrySet()) { 
                wrapper.addInitParameter(entry.getKey(), entry.getValue()); 
            } 
            wrapper.setRunAs(servlet.getRunAs()); 
            Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs(); 
            for (SecurityRoleRef roleRef : roleRefs) { 
                wrapper.addSecurityReference( 
                        roleRef.getName(), roleRef.getLink()); 
            } 
            wrapper.setServletClass(servlet.getServletClass()); 
            MultipartDef multipartdef = servlet.getMultipartDef(); 
            if (multipartdef != null) { 
                if (multipartdef.getMaxFileSize() != null && 
                        multipartdef.getMaxRequestSize()!= null && 
                        multipartdef.getFileSizeThreshold() != null) { 
                    wrapper.setMultipartConfigElement(new 
 MultipartConfigElement( 
                            multipartdef.getLocation(), 
                            Long.parseLong(multipartdef.getMaxFileSize()), 
                            Long.parseLong(multipartdef.getMaxRequestSize()), 
                            Integer.parseInt( 
                                    multipartdef.getFileSizeThreshold()))); 
                } else { 
                    wrapper.setMultipartConfigElement(new 
 MultipartConfigElement( 
                            multipartdef.getLocation())); 
                } 
            } 
            if (servlet.getAsyncSupported() != null) { 
                wrapper.setAsyncSupported( 
                        servlet.getAsyncSupported().booleanValue()); 
            } 
            context.addChild(wrapper); 
 } 

getLoadOnStartup();是返回該類的整形成員變數的loadOnStartup,而該整形的變數通過

  public void setLoadOnStartup(String loadOnStartup) {
        this.loadOnStartup = Integer.valueOf(loadOnStartup);
    }

這個方法沒有任何處理的意思,我們所知的,如果是非整數或者空字串,它就會報異常,那麼他的內部機制應該是當資料異常時,loadOnStartup 很有可能會被賦予一個整形的數值進行初始化。

那麼我們去試著查詢一下它的底層:

public void setLoadOnStartupString(String value) {


        try {
            setLoadOnStartup(Integer.parseInt(value));
        } catch (NumberFormatException e) {
            setLoadOnStartup(0);
        }
    }
 我們可以看到,當資料異常時,他會直接將loadOnStartup()直接設定為0,也就是說一旦異常肯定會被最先載入的。

思考二,那麼當<load-on-Startup>x</load-on-Startup>x值相同時,怎麼對他進行初始化呢?容器的自主選擇是指什麼?