APDPlat接管了Spring的启动关闭权,为各类运行其上的开源框架和类库的无缝集成提供了支持。前端
固然,你们都知道,一个JAVA EE Web应用的入口点是web.xml,APDPlat固然也不例外,咱们看看APDPlat是如何接管Spring的启动关闭权的:java
<listener> <description>通过定制的spring监听器</description> <listener-class>org.apdplat.platform.spring.APDPlatContextLoaderListener</listener-class> </listener>
/** * 自定义Spring的ContextLoaderListener * @author 杨尚川 */ public class APDPlatContextLoaderListener extends ContextLoaderListener { @Override public void contextInitialized(ServletContextEvent event) { //接管系统的启动 SystemListener.contextInitialized(event); super.contextInitialized(event); } @Override public void contextDestroyed(ServletContextEvent event) { //接管系统的关闭 SystemListener.contextDestroyed(event); super.contextDestroyed(event); } }
在Spring启动和关闭以前,都会先调用org.apdplat.module.system.service.SystemListener来作预处理。git
这只是接管启动和关闭权,关于无缝集成所作的定制请看org.apdplat.platform.spring、org.apdplat.platform.struts、org.apdplat.platform.compass这三个包里面的类,这里不作说明。github
本文主要分析SystemListener在系统启动和关闭的时候都分别作了什么处理。web
系统启动流程:spring
一、获取ContextPath数据库
contextPath=sce.getServletContext().getContextPath();
public static String getContextPath() { return contextPath; }
在部署APDPlat的时候,可能会有两种状况:一是部署在ROOT目录下,ContextPath为空,则地址为http://192.168.0.100;二是部署在非ROOT目录下,假设ContextPath为APDPlat_Web,则地址为http://192.168.0.100/APDPlat_Web。前端EXT JS和JSP以及后台服务在处理绝对路径和记录日志等状况的时候须要知道ContextPath的值,该值在系统启动的时候从应用服务器中得到,保存为静态变量,并经过静态方法暴露给系统使用。服务器
二、获取RealPath框架
basePath=sce.getServletContext().getRealPath("/"); FileUtils.setBasePath(basePath);
整个APDPlat系统中的文件操做都以basePath为基础,经过basePath的值,咱们能够得知Web应用存放在服务器上面的本地磁盘绝对路径,如:D:\Workspaces\NetBeansProjects\APDPlat2.5\APDPlat_Web\target\APDPlat_Web-2.5\,这样咱们就能够对Web应用中的全部文件进行IO操做。ide
三、改变系统属性user.dir的值
userDir=FileUtils.getAbsolutePath("/WEB-INF/classes/data/"); System.setProperty("user.dir", userDir);
把user.dir从新指定到Web应用的/WEB-INF/classes/data/目录,此目录会存放索引文件,初始导入的数据文件。
四、为spring的配置作预处理
public static void prepareForSpring(){ //供spring扫描组件用 String basePackage=PropertyHolder.getProperty("basePackages"); String localBasePackage=PropertyHolder.getProperty("basePackages.local"); if(StringUtils.isNotBlank(localBasePackage)){ basePackage=basePackage+","+localBasePackage; } System.setProperty("basePackage", basePackage); }
这里为用户在项目中自定义扫描组件的范围提供支持,用户可在config.local.properties配置文件中定义变量basePackages.local的值为本身的包名称。
五、注册模块
Enumeration<URL> ps = Thread.currentThread().getContextClassLoader().getResources("META-INF/services/module.xml");
根据模块描述文件module.xml识别类路径下的全部模块,注册模块,提取web资源和数据,为后续的组件扫描、模块初始化、数据库同步作准备。
六、解析全部的dic.xml文件,并生成供客户端EXT JS调用的文件
DictionaryGenerator.generateDic(basePath);
七、记录服务器启动日志(如启用)
//保存服务器启动日志 BufferLogCollector.collect(runingTime);
八、启动内存监视线程(如启用)
int circle=PropertyHolder.getIntProperty("monitor.memory.circle"); memoryMonitorThread=new MemoryMonitorThread(circle); memoryMonitorThread.start();
系统关闭流程:
一、记录用户注销日志(如启用)
UserLoginListener.forceAllUserOffline();
二、记录服务器关闭日志(如启用)
//保存服务器关闭日志 BufferLogCollector.collect(runingTime);
三、中止内存监视线程(如启用)
memoryMonitorThread.running=false; memoryMonitorThread.interrupt();
四、处理缓冲区中的日志
//在关闭系统以前,处理缓冲区中的日志 BufferLogCollector.close();
五、卸载JDBC驱动
private static void deregisterDrivers() { Enumeration<Driver> drivers=DriverManager.getDrivers(); while(drivers.hasMoreElements()){ Driver driver=drivers.nextElement(); try { DriverManager.deregisterDriver(driver); } catch (SQLException e) { LOG.warn("卸载JDBC驱动失败:"+driver, e); LOG.warn("Fail to uninstall JDBC driver:"+driver, e, Locale.ENGLISH); } } }