天天看點

Liferay 啟動過程分析3-處理啟動事件(第一部分)

在MainServlet啟動Struts中央控制器之後第一件事情就是去處理啟動事件:

protected void processStartupEvents() throws Exception { 

    StartupAction startupAction = new StartupAction(); 

    startupAction.run(null); 

它會去調用StartupAction中的run方法,進而調用doRun()方法,這裡又做了很多事情:

(1)它在控制台列印出産品版本資訊:

// Print release information 

        System.out.println("Starting " + ReleaseInfo.getReleaseInfo()); 

這個版本資訊,可以從ReleaseInfo類中得到:

public static final String getReleaseInfo() { 

        return releaseInfo; 

    } 

static String releaseInfo = 

        releaseInfoPrefix + name + " " + versionDisplayName + " (" + codeName + 

            " / Build " + build + " / " + date + ")" + releaseInfoSuffix; 

這些常量都可以在ReleaseInfo類找到:是以控制台中顯示:

Starting Liferay Portal Community Edition 6.1.0 CE (Paton / Build 6100 / January 6, 2012) 

(2)清空鎖資訊:

try { 

            LockLocalServiceUtil.clear(); 

        } 

它會調用LockLocalServiceUtil中的clear()方法:

public static void clear() 

    throws com.liferay.portal.kernel.exception.SystemException { 

    getService().clear(); 

進而調用LockLocalServiceImpl類中的clear()方法:

public void clear() throws SystemException { 

        lockPersistence.removeByLtExpirationDate(new Date()); 

進而調用LocalPersistenceImpl類的removeByLtExpirationDate方法:

/** 

 * Removes all the locks where expirationDate < ? from the database. 

 * 

 * @param expirationDate the expiration date 

 * @throws SystemException if a system exception occurred 

 */ 

public void removeByLtExpirationDate(Date expirationDate) 

    throws SystemException { 

    for (Lock lock : findByLtExpirationDate(expirationDate)) { 

        remove(lock); 

它會從資料庫中移除所有到期的鎖,以目前日期為标準,下面就不展開了。

(3)關閉所有的hook:

它讓目前應用的運作時去關閉所有的Hook:

Runtime runtime = Runtime.getRuntime(); 

    runtime.addShutdownHook(new Thread(new ShutdownHook())); 

每個Hook都開啟一個新的Thread來關閉,它實作Runnable接口,僅僅做一些列印工作:

public class ShutdownHook implements Runnable { 

    public void run() { 

        if (GetterUtil.getBoolean( 

                System.getProperty("shutdown.hook.print.full.thread.dump"))) { 

            printFullThreadDump(); 

... 

而這些hook都會添加到Liferay應用的運作時中,運作時會先檢查是否有shutdown hook的權限,然後再做shutdown hook的事情:

public void addShutdownHook(Thread hook) { 

    SecurityManager sm = System.getSecurityManager(); 

    if (sm != null) { 

        sm.checkPermission(new RuntimePermission("shutdownHooks")); 

    ApplicationShutdownHooks.add(hook); 

遞歸找下去,會發現這個permission定義在%LIFERAY_HOME%/tomcat-7.0.23/conf/catalina.policy中,是以我們擁有這個權限:

 ... 

permission java.io.FilePermission 

         "${catalina.base}${file.separator}logs${file.separator}*", "read, write"; 

        permission java.lang.RuntimePermission "shutdownHooks"; 

        permission java.lang.RuntimePermission "getClassLoader"; 

        permission java.lang.RuntimePermission "setContextClassLoader"; 

之後,就把hook添加到ApplicationShutdownHooks的hashmap中來關閉:

static { 

      Shutdown.add(1 /* shutdown hook invocation order */, 

          new Runnable() { 

              public void run() { 

                  runHooks(); 

              } 

          }); 

  } 

(4)配置Security Manager

// Security manager 

        String portalSecurityManagerStrategy = 

            PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY; 

        if (portalSecurityManagerStrategy.equals("smart")) { 

            if (ServerDetector.isWebSphere()) { 

                portalSecurityManagerStrategy = "none"; 

            } 

            else { 

                portalSecurityManagerStrategy = "default"; 

        if (portalSecurityManagerStrategy.equals("liferay")) { 

            if (System.getSecurityManager() == null) { 

                System.setSecurityManager(new PortalSecurityManager()); 

        else if (portalSecurityManagerStrategy.equals("none")) { 

            System.setSecurityManager(null); 

它會先檢查SecurityManager的政策:

public static final String PORTAL_SECURITY_MANAGER_STRATEGY = PropsUtil.get(PropsKeys.PORTAL_SECURITY_MANAGER_STRATEGY); 

它的key來自PropsKeys接口:

public static final String PORTAL_SECURITY_MANAGER_STRATEGY = "portal.security.manager.strategy"; 

最終我們去通路portal.properties可以看到:

## 

## Security Manager 

    # 

    # Set this property to "default" to use the default security manager 

    # configured by the application server. A security manager will not be used 

    # if the application server did not configure one. 

    # Set this property to "liferay" to use Liferay's security manager if the 

    # application server has not configured a security manager. 

    # Set this property to "none" to explicitly remove the security manager 

    # regardless of whether one is configured. This ensures that the portal is 

    # run in a JVM without a security manager. 

    # Set this property to "smart" to allow the portal decide which strategy to 

    # use based on which application server it is on. 

    portal.security.manager.strategy=smart 

是以,它用的是"smart"政策,是以執行下面代碼:

if (portalSecurityManagerStrategy.equals("smart")) { 

        if (ServerDetector.isWebSphere()) { 

            portalSecurityManagerStrategy = "none"; 

        else { 

            portalSecurityManagerStrategy = "default"; 

因為我們的Server用的是tomcat,而不是websphere,是以我們執行else代碼段,也就是我們的portalSecurityManagerStrategy用的是"default",這種情況下使用tomcat應用伺服器的安全政策。

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

繼續閱讀