因爲在深刻jvm虛擬機中看到了有部分說道class能夠經過網絡的方式加載,因而就想到了是否是能夠經過在網絡上發佈jar包,而後程序動態加載網絡上的jar包(可拓展爲熱更新)java
調用模塊 https://coding.net/u/mich/p/easytry/git/tree/master/src/com/netclassloadergit
實現模塊 https://coding.net/u/mich/p/easytry/git/tree/master/netlogicImpl數組
接口模塊 https://coding.net/u/mich/p/easytry/git/tree/master/netlogicInterface網絡
該內容主要由三部分組成jvm
接口模塊相對來講比較簡單,兩個接口ide
package com.netresource.logic; /** * Created by Mich on 2017/7/22. */ public interface ISayHello { Object sayHello(); }
package com.netresource.logic; /** * Created by Mich on 2017/7/22. */ public interface ISayWorld { Object sayWorld(); }
實現模塊須要先導入剛纔接口模塊,而後寫兩個接口的實現類函數
package com.netlogic; import com.netresource.logic.ISayHello; /** * Created by Mich on 2017/7/22. */ public class SayHelloImpl implements ISayHello { @Override public Object sayHello() { return "Hello"; } }
package com.netlogic; import com.netresource.logic.ISayWorld; /** * Created by Mich on 2017/7/22. */ public class SayWorldImpl implements ISayWorld { @Override public Object sayWorld() { return "World"; } }
你會發現還有兩個util,fileutil主要是我一直使用的對文件的一些處理比較方便,就直接引用了,PropertiesUtil主要是協議文件的生成工具,經過傳入實現類的包名,而後掃描該包下的全部類把接口和實現作對應關係存放在output.properties文件中,須要注意的是,若是一個接口並不支持有多個實現類,可是一個實現類實現多個接口是能夠的工具
最後將實現類打jar包,以及將協議文件上傳至網絡,我這裏圖方便直接放到了coding上https://coding.net/u/mich/p/easytry/git/raw/master/src/com/netclassloader/output/netlogicImpl.jar測試
https://coding.net/u/mich/p/easytry/git/raw/master/src/com/netclassloader/output/output.propertiesthis
一樣調用模塊須要引用接口模塊的jar包,而後介紹一下調用模塊的具體目錄結構(這裏無視output文件夾,這主要是我剛纔上傳的兩個文件,jar包和協議文件,爲了在一個模塊裏才放這裏,實際不須要這個文件夾)
NetClassManager,因爲代碼有點多就不在這裏顯示了,具體能夠再coding上去看,這裏主要介紹一下結構
NetClassLoader類加載器
package com.netclassloader; /** * Created by Mich on 17/7/17. */ public class NetClassLoader extends ClassLoader { private NetClassManager netClassManager; public NetClassLoader(NetClassManager netClassManager) { this.netClassManager = netClassManager; } @Override protected Class<?> findClass(String name) throws ClassNotFoundException { byte[] bytes = netClassManager.getClassMap().get(name); return defineClass(name, bytes, 0, bytes.length); } }
這個就比較簡單了,繼承了ClassLoader,構造函數傳入剛剛說明的管理類NetClassManager,而後重寫了findClass的方法,經過管理類的map來獲取字節數組
Main做爲測試的入口函數
public static void main(String[] args) {
String jarUrl = "https://coding.net/u/mich/p/easytry/git/raw/master/src/com/netclassloader/output/netlogicImpl.jar"; String propertiesUrl = "https://coding.net/u/mich/p/easytry/git/raw/master/src/com/netclassloader/output/output.properties"; NetClassManager netClassManager = new NetClassManager(propertiesUrl, jarUrl); NetClassLoader classLoader = new NetClassLoader(netClassManager); ISayHello hello = netClassManager.getService(classLoader, ISayHello.class); ISayWorld world = netClassManager.getService(classLoader, ISayWorld.class); System.out.println(hello.sayHello()); System.out.println(world.sayWorld()); }
最後就是比較簡單的調用了,運行結果
其實這裏也只是拋磚,若是具體使用,應該還須要版本控制,能夠有一個專門的類,或者手動調用,去獲取最新的jar包,和最新的協議接口文件,固然更好一點能夠再添加一個實現類的版本控制,這樣就須要修改的粒度更小了。對了若是要添加動態更新還須要修改NetClassLoader類,如今目前只是第一次加載處理,若是有更新,就須要重寫loadClass方法了。最後想一想其實協議文件,和版本控制能夠直接放在jar包中。。。等下次再繼續改進吧。。。