我们回到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的初始化。