我們回到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,如需轉載請自行聯系原作者