1、 類加載器java
要深刻理解openfire插件機制的內部原理,必需要深刻了解一下java的類加載器。類加載器做用是加載 Java 類到 Java 虛擬機中。
加載過程以下:Java 源程序編譯後轉換成 Java 字節碼(.class),類加載器負責讀取 字節碼,並轉換成java.lang.Class類的一個實例。web
系統提供的類加載器有:bootstrap
1、引導類加載器(bootstrap class loader)tomcat
jvm內置的加載器,是用C++實現的。
引導類加載器的加載路徑,由系統屬性sun.boot.class.path來指定,它的默認值指向jre的classes目錄,及lib目錄下rt.jar等幾個jar文件。
可經過-Dsun.boot.class.path來手工指定,也可經過-Xbootclasspath等屬性來指定。app
2、擴展類加載器(extensions class loader)jvm
類加載路徑由java.ext.dirs來肯定,java.ext.dirs屬性值指向一個或多個目錄,默認jre/lib/ext,加載 Java 的擴展庫$java_home/jre/ext/*.jar。函數
3、應用類加載器(application class loader)spa
主要負責加載java –classpath、-Djava.class.path或$CLASSPATH環境變量所指的目錄下的類與jar包。 通常來講,Java 應用的類及其依賴jar包也都是由它來完成加載的。能夠經過 ClassLoader.getSystemClassLoader()來獲取它。插件
Openfire中自定義的類加載器:線程
1、JiveClassLoader:類加載路徑爲openfireHome/lib下的全部jar,zip文件,加載openfire所依賴的核心類庫。
2、PluginClassLoader:openfire插件加載的時候,會爲每一個插件建立一個PluginClassLoader對 象,它加載路徑爲插件目錄下的classes,database,i18n,web目錄,與lib目錄下全部的jar,zip文件,但排除plugin- pluginName.jar文件
2、 內部原理
1、openfire插件相似於web容器下的多個獨立的web應用,openfire就是容器,負責管理插件的生命週期。
2、openfire經過定時的掃描openfire/plugins目錄下的.jar、.war文件及同名的目錄,跟蹤他們的變化,來決定加 載仍是卸載一個插件。這跟tomcat很相似,主要的差別在與openfire的PluginClassLoader沒有tomcat的 WebAppClassLoader那樣的優先覆蓋機制,openfire嚴格的遵循了java.lang.ClassLoader類的委託機制。
3、因爲ClassLoader的委託模型,由JiveClassLoader加載的核心類,沒法經過委託PluginClassLoader 來隱式加載到插件類,即openfire/lib下的核心類不能依賴於插件中的類,而插件類卻能夠經過委託JiveClassLoader來加載核心類, 插件類可使用核心類,這個開發中須要注意,避免產生依賴錯亂。
3、 生命週期
1、加載
加載一個插件時,先解壓.jar/.war文件,讀取插件目錄下的plugin.xml,獲得Plugin接口的一個實現類 XXXPlugin,經過建立一個新的PluginLoader對象來加載XXXPlugin,調用默認的無參數構造函數建立一個XXXPlugin對象
2、初始化
經過執行initializePlugin,讓插件初始化
3、使用
初始化後插件即開始工做,處理商業邏輯
4、銷燬
卸載一個插件時,首先調用這個XXXPlugin對象的destroyPlugin方法,並從PluginManager中刪 除這個XXXPlugin對象,而後經過去除PluginClassLoader的引用,讓插件中的全部類等待垃圾回收,並刪除這個插件目錄。 destroyPlugin方法,應該終止它所開啓的線程,應該刪除全部由上層類加載器對PluginClassLoader加載的類實例的引用,保證插 件的被垃圾回收