天天看點

Liferay 啟動過程分析4-初始化Servlet上下文池

 我們回到MainServlet類的init()方法中,在執行processStartupEvents()之後,我們開始初始化Servlet上下文池:

if (_log.isDebugEnabled()) { 

            _log.debug("Initialize servlet context pool"); 

        } 

        try { 

            initServletContextPool(); 

        catch (Exception e) { 

            _log.error(e, e); 

它會調用以下方法:

protected void initServletContextPool() throws Exception { 

        ServletContext servletContext = getServletContext(); 

        String contextPath = PortalUtil.getPathContext(); 

        ServletContextPool.put(contextPath, servletContext); 

    } 

首先,它擷取Servlet上下文對象,然後它去取得contextPath.這個字元串是通過PortalUtil.getPathContext()獲得,進而調用PortalImpl的getPathContext()方法:

public String getPathContext() { 

    return _pathContext; 

這個值設定在PortalImpl類的構造器中,我們将其解析出來:

.. 

// Paths 

_pathProxy = PropsValues.PORTAL_PROXY_PATH; 

_pathContext = ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX); 

_pathContext = _pathProxy.concat(_pathContext); 

解析_pathProxy=PropsValues.PORTAL_PROXY_PATH:

這個值最終定義在portal.properties中:

   # Set this property if the application server is served behind a proxy and 

   # a prefix needs to be added to the portal servlet context path. This prefix 

   # will also be added to static resources served by layout templates, 

   # portlets, and themes. 

   # 

   portal.proxy.path= 

解析_pathContext=ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX): 

先找到PropsValues.PORTAL_CTX的取值,很容易發現它最終定義在portal.properties中:

  # Specify the path of the portal servlet context. This is needed because 

  # javax.servlet.ServletContext did not have access to the context path until 

  # Java EE 5. 

  # 

  # Set this property if you deploy the portal to another path besides root. 

  portal.ctx=/ 

然後,我們來解析 ContextPathUtil.getContextPath("/"):

對應解析代碼為:

public static String getContextPath(String contextPath) { 

        contextPath = GetterUtil.getString(contextPath); 

        if ((contextPath.length() == 0) || 

            contextPath.equals(StringPool.SLASH)) { 

            contextPath = StringPool.BLANK; 

        else if (!contextPath.startsWith(StringPool.SLASH)) { 

            contextPath = StringPool.SLASH.concat(contextPath); 

        return contextPath; 

先看02行,它調用GetterUtil的getString方法:

public static String getString(String value) { 

    return getString(value, DEFAULT_STRING); 

最終調用的代碼為:

public static String get(String value, String defaultValue) { 

    if (value == null) { 

        return defaultValue; 

    value = value.trim(); 

    if (value.indexOf(CharPool.RETURN) != -1) { 

        value = StringUtil.replace( 

            value, StringPool.RETURN_NEW_LINE, StringPool.NEW_LINE); 

    return value; 

是以,他沒有進入任何判斷,直接傳回"/",

然後我們看03行:

可以發現它比對contextPath.equals(StringPool.SLASH)),是以最終執行 contextPath = StringPool.BLANK, 也就是把contextPath設為空串。

它就是_pathContext的值。

解析_pathContext = _pathProxy.concat(_pathContext); 

因為我們_pathProxy為空,而_pathContext也為空,是以最終結果_pathContext為空。

最終,我們在MainServlet的initServletContextPool方法中執行以下語句:

ServletContextPool.put(contextPath, servletContext); 

它就是在ServletContextPool中添加一個key-value對,于是就完成了ServletContextPool的初始化。

本文轉自 charles_wang888 51CTO部落格,原文連結:http://blog.51cto.com/supercharles888/906005,如需轉載請自行聯系原作者