APDPlat的系統啓動和關閉流程剖析

 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);
            }
        }
    }

 

APDPlat託管在Github

相關文章
相關標籤/搜索