Liferay 启动过程分析
前几天搞了一个BUG,吧精力耗尽,也激发了我对Liferay这个框架内部的探究欲望。所以这几天端午节准备对Liferay框架启动过程进行深入研究,来满足自己的好奇心。
当我们在地址栏中访问http://localhost:8080时,因为Liferay应用本质上也是一个web应用,所以它会去找ROOT应用的web.xml,因为定义了<welcome-file-list>:
<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list>
所以,它会去找index.jsp:
... <% ... String redirect = null; LayoutSet layoutSet = (LayoutSet)request.getAttribute(WebKeys.VIRTUAL_HOST_LAYOUT_SET); if (layoutSet != null) { long defaultPlid = LayoutLocalServiceUtil.getDefaultPlid(layoutSet.getGroupId(), layoutSet.isPrivateLayout()); if (defaultPlid != LayoutConstants.DEFAULT_PLID) { Layout layout = LayoutLocalServiceUtil.getLayout(defaultPlid); ServicePreAction servicePreAction = (ServicePreAction)InstancePool.get(ServicePreAction.class.getName()); ThemeDisplay themeDisplay = servicePreAction.initThemeDisplay(request, response); redirect = PortalUtil.getLayoutURL(layout, themeDisplay); } else { redirect = PortalUtil.getPathMain(); } } else { redirect = PortalUtil.getHomeURL(request); } if (!request.isRequestedSessionIdFromCookie()) { redirect = PortalUtil.getURLWithSessionId(redirect, session.getId()); } response.setHeader(HttpHeaders.LOCATION, redirect); response.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); %> <html> <head> <title></title> <meta content="1; url=<%= redirect %>" http-equiv="refresh" /> </head> <body onload="javascript:location.replace('<%= redirect %>')"> </body> </html>
其中,最值得看的就是<body onload="javascript:location.replace...),它会在DOM树加载完毕之后触发,那么我们感兴趣的是,这个<%=redirect%>到底是什么呢?
寻找<%=redirect%>的值
为此,我们去看上面那段代码,因为第一次登录,所以什么用户信息都没有,所以实际上走的是以下的代码段:
else { redirect = PortalUtil.getPathMain(); }
然后这段代码会调用PortalUtil中的:
public static String getPathMain() { return getPortal().getPathMain(); }
然后调用PortalImpl类中的:
public String getPathMain() { return _pathMain; }
而这个_pathMain是由该类中以下代码提供的,在PortalImpl构造器中:
// Paths _pathProxy = PropsValues.PORTAL_PROXY_PATH; _pathContext = ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX); _pathContext = _pathProxy.concat(_pathContext); _pathFriendlyURLPrivateGroup = _pathContext + _PRIVATE_GROUP_SERVLET_MAPPING; _pathFriendlyURLPrivateUser = _pathContext + _PRIVATE_USER_SERVLET_MAPPING; _pathFriendlyURLPublic = _pathContext + _PUBLIC_GROUP_SERVLET_MAPPING; _pathImage = _pathContext + PATH_IMAGE; _pathMain = _pathContext + PATH_MAIN; // Groups
所以_pathMain为_pathContext+PATH_MAIN ,我们依次来解析:
解析 _pathContext:
对于_pathContext,它是ContextPathUtil.getContextPath(PropsValues.PORTAL_CTX);
其中PropsValues.PORTAL_CTX是:
public static final String PORTAL_CTX = PropsUtil.get(PropsKeys.PORTAL_CTX);
它会去找PropsKeys接口中的常量定义:
public static final String PORTAL_CTX = "portal.ctx";
然后找到并替换之后,去执行PropsUtil.get("portal.ctx");
public static String get(String key) { return _instance._get(key); }
它会访问
private String _get(String key) { return _getConfiguration().get(key); }
这段代码最终会访问配置文件,然后读取key-value对到Configuration中,我们在portal.properties中找到了portal.ctx的定义:
##
## Portal Context
##
#
# 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=/
所以portal.ctx=/
解析PATH_MAIN:
它在Portal接口中有定义:
public static final String PATH_MAIN = "/c";
所以综上所述,在PortalImpl构造器中的_pathMain = _pathContext + PATH_MAIN="/"+"/c"="//c"
它就是<%=redirect%>的值。
所以当index.jsp中DOM树加载完毕之后,它会去执行:
<body onload="javascript:location.replace('//c')">
共同学习,写下你的评论
评论加载中...
作者其他优质文章