Liferay 启动过程分析3-处理启动事件(第一部分)

简介:

在MainServlet启动Struts中央控制器之后第一件事情就是去处理启动事件:

 
 
  1. protected void processStartupEvents() throws Exception { 
  2.     StartupAction startupAction = new StartupAction(); 
  3.  
  4.     startupAction.run(null); 

 

它会去调用StartupAction中的run方法,进而调用doRun()方法,这里又做了很多事情:

(1)它在控制台打印出产品版本信息:

 
 
  1. // Print release information 
  2.  
  3.         System.out.println("Starting " + ReleaseInfo.getReleaseInfo()); 

这个版本信息,可以从ReleaseInfo类中得到:

 
 
  1. public static final String getReleaseInfo() { 
  2.         return releaseInfo; 
  3.     } 
 
 
  1. static String releaseInfo = 
  2.         releaseInfoPrefix + name + " " + versionDisplayName + " (" + codeName + 
  3.             " / Build " + build + " / " + date + ")" + releaseInfoSuffix; 

这些常量都可以在ReleaseInfo类找到:所以控制台中显示:

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

 

(2)清空锁信息:

 
 
  1. try { 
  2.             LockLocalServiceUtil.clear(); 
  3.         } 

它会调用LockLocalServiceUtil中的clear()方法:

 
 
  1. public static void clear() 
  2.     throws com.liferay.portal.kernel.exception.SystemException { 
  3.     getService().clear(); 

进而调用LockLocalServiceImpl类中的clear()方法:

 
 
  1. public void clear() throws SystemException { 
  2.         lockPersistence.removeByLtExpirationDate(new Date()); 
  3.     } 

进而调用LocalPersistenceImpl类的removeByLtExpirationDate方法:

 
 
  1. /** 
  2.  * Removes all the locks where expirationDate < ? from the database. 
  3.  * 
  4.  * @param expirationDate the expiration date 
  5.  * @throws SystemException if a system exception occurred 
  6.  */ 
  7. public void removeByLtExpirationDate(Date expirationDate) 
  8.     throws SystemException { 
  9.     for (Lock lock : findByLtExpirationDate(expirationDate)) { 
  10.         remove(lock); 
  11.     } 

它会从数据库中移除所有到期的锁,以当前日期为标准,下面就不展开了。

 

(3)关闭所有的hook:

它让当前应用的运行时去关闭所有的Hook:

 
 
  1. Runtime runtime = Runtime.getRuntime(); 
  2.  
  3.     runtime.addShutdownHook(new Thread(new ShutdownHook())); 

每个Hook都开启一个新的Thread来关闭,它实现Runnable接口,仅仅做一些打印工作:

 
 
  1. public class ShutdownHook implements Runnable { 
  2.  
  3.     public void run() { 
  4.         if (GetterUtil.getBoolean( 
  5.                 System.getProperty("shutdown.hook.print.full.thread.dump"))) { 
  6.  
  7.             printFullThreadDump(); 
  8.         } 
  9.     } 
  10. ... 

而这些hook都会添加到Liferay应用的运行时中,运行时会先检查是否有shutdown hook的权限,然后再做shutdown hook的事情:

 
 
  1. public void addShutdownHook(Thread hook) { 
  2.     SecurityManager sm = System.getSecurityManager(); 
  3.     if (sm != null) { 
  4.         sm.checkPermission(new RuntimePermission("shutdownHooks")); 
  5.     } 
  6.     ApplicationShutdownHooks.add(hook); 
  7.     } 

递归找下去,会发现这个permission定义在%LIFERAY_HOME%/tomcat-7.0.23/conf/catalina.policy中,所以我们拥有这个权限:

 
 
  1.  ... 
  2. permission java.io.FilePermission 
  3.          "${catalina.base}${file.separator}logs${file.separator}*""read, write"
  4.  
  5.         permission java.lang.RuntimePermission "shutdownHooks"
  6.         permission java.lang.RuntimePermission "getClassLoader"
  7.         permission java.lang.RuntimePermission "setContextClassLoader"
  8. ... 

 

之后,就把hook添加到ApplicationShutdownHooks的hashmap中来关闭:

 
 
  1. static { 
  2.       Shutdown.add(1 /* shutdown hook invocation order */
  3.           new Runnable() { 
  4.               public void run() { 
  5.                   runHooks(); 
  6.               } 
  7.           }); 
  8.   } 

 

(4)配置Security Manager

 
 
  1. // Security manager 
  2.  
  3.         String portalSecurityManagerStrategy = 
  4.             PropsValues.PORTAL_SECURITY_MANAGER_STRATEGY; 
  5.  
  6.         if (portalSecurityManagerStrategy.equals("smart")) { 
  7.             if (ServerDetector.isWebSphere()) { 
  8.                 portalSecurityManagerStrategy = "none"
  9.             } 
  10.             else { 
  11.                 portalSecurityManagerStrategy = "default"
  12.             } 
  13.         } 
  14.  
  15.         if (portalSecurityManagerStrategy.equals("liferay")) { 
  16.             if (System.getSecurityManager() == null) { 
  17.                 System.setSecurityManager(new PortalSecurityManager()); 
  18.             } 
  19.         } 
  20.         else if (portalSecurityManagerStrategy.equals("none")) { 
  21.             System.setSecurityManager(null); 
  22.         } 

它会先检查SecurityManager的策略:

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

它的key来自PropsKeys接口:

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

最终我们去访问portal.properties可以看到:

 
 
  1. ## 
  2. ## Security Manager 
  3. ## 
  4.  
  5.     # 
  6.     # Set this property to "default" to use the default security manager 
  7.     # configured by the application server. A security manager will not be used 
  8.     # if the application server did not configure one. 
  9.     # 
  10.     # Set this property to "liferay" to use Liferay's security manager if the 
  11.     # application server has not configured a security manager. 
  12.     # 
  13.     # Set this property to "none" to explicitly remove the security manager 
  14.     # regardless of whether one is configured. This ensures that the portal is 
  15.     # run in a JVM without a security manager. 
  16.     # 
  17.     # Set this property to "smart" to allow the portal decide which strategy to 
  18.     # use based on which application server it is on
  19.     # 
  20.     portal.security.manager.strategy=smart 

所以,它用的是"smart"策略,所以执行下面代码:

 
 
  1. if (portalSecurityManagerStrategy.equals("smart")) { 
  2.         if (ServerDetector.isWebSphere()) { 
  3.             portalSecurityManagerStrategy = "none"
  4.         } 
  5.         else { 
  6.             portalSecurityManagerStrategy = "default"
  7.         } 
  8.     } 

因为我们的Server用的是tomcat,而不是websphere,所以我们执行else代码段,也就是我们的portalSecurityManagerStrategy用的是"default",这种情况下使用tomcat应用服务器的安全策略。





本文转自 charles_wang888 51CTO博客,原文链接:http://blog.51cto.com/supercharles888/905775,如需转载请自行联系原作者

目录
相关文章
|
Java jenkins 持续交付
Spring Boot 项目脚本(启动、停止、重启、状态)
此脚本用来管理 SpringBoot 项目的进程状态。 有提示功能。 把脚本丢到项目文件夹, 添加执行权限即可。 如果 jenkins 使用这个脚本, 需要在 java -jar 命令前添加 BUILD_ID=dontKillMe , 不然 jenkins 会杀掉进程。
439 0
Spring Boot 项目脚本(启动、停止、重启、状态)