熱載入解除安裝jar包
阿新 • • 發佈:2020-12-30
熱載入解除安裝jar包
2020-12-29
1 類層次
2 原始碼
hot-load-unload-jar專案
PluginClassLoader.java內容如下:
package com.test; import java.net.JarURLConnection; import java.net.URL; import java.net.URLClassLoader; import java.net.URLConnection; import java.util.ArrayList; import java.util.List; /** * 外掛類載入器,在外掛目錄中搜索jar包,併為發現的資源(jar)構造一個類載入器,將對應的jar新增到classpath中 *View Code@author strawxdl */ public class PluginClassLoader extends URLClassLoader { private List<JarURLConnection> cachedJarFiles = new ArrayList<JarURLConnection>(); public PluginClassLoader() { super(new URL[] {}, findParentClassLoader()); } /** * 將指定的檔案url新增到類載入器的classpath中去,並快取jar connection,方便以後解除安裝jar *@param 一個可想類載入器的classpath中新增的檔案url */ public void addURLFile(URL file) { try { // 開啟並快取檔案url連線 URLConnection uc = file.openConnection(); if (uc instanceof JarURLConnection) { uc.setUseCaches(true); ((JarURLConnection) uc).getManifest(); cachedJarFiles.add((JarURLConnection)uc); } }catch (Exception e) { System.err.println("Failed to cache plugin JAR file: " + file.toExternalForm()); } addURL(file); } /** * 解除安裝jar包 */ public void unloadJarFiles() { for (JarURLConnection url : cachedJarFiles) { try { System.err.println("Unloading plugin JAR file " + url.getJarFile().getName()); url.getJarFile().close(); url=null; } catch (Exception e) { System.err.println("Failed to unload JAR file\n"+e); } } } /** * 定位基於當前上下文的父類載入器 * @return 返回可用的父類載入器. */ private static ClassLoader findParentClassLoader() { ClassLoader parent = PluginManager.class.getClassLoader(); if (parent == null) { parent = PluginClassLoader.class.getClassLoader(); } if (parent == null) { parent = ClassLoader.getSystemClassLoader(); } return parent; } }
PluginManager.java內容如下:
package com.test; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; /** * jar包 熱載入/解除安裝 的初步實現 * https://www.cnblogs.com/xiaodl/p/plugin_hot_load.html */ public class PluginManager { static{ System.out.println(PluginManager.class.getName()); } private Map<String ,PluginClassLoader> pluginMap = new HashMap<String,PluginClassLoader>(); private static String packagename = "com.test.Plugin1"; public PluginManager(){ } public void doSome(String pluginName){ try{ Class<?> forName = Class.forName(packagename, true, getLoader(pluginName));//this.pluginMap.get(pluginName).loadClass(packagename); Plugin ins = (Plugin)forName.newInstance(); ins.doSome(); }catch(Exception e){ e.printStackTrace(); } } private void addLoader(String pluginName,PluginClassLoader loader){ this.pluginMap.put(pluginName, loader); } private PluginClassLoader getLoader(String pluginName){ return this.pluginMap.get(pluginName); } public void loadPlugin(String pluginName){ this.pluginMap.remove(pluginName); PluginClassLoader loader = new PluginClassLoader(); String pluginurl = "jar:file:/D:/code/plugindemo/target/"+pluginName+".jar!/"; URL url = null; try { url = new URL(pluginurl); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } loader.addURLFile(url); addLoader(pluginName, loader); System.out.println("load " + pluginName + " success"); } public void unloadPlugin(String pluginName){ this.pluginMap.get(pluginName).unloadJarFiles(); this.pluginMap.remove(pluginName); } }View Code
TestMain.java內容如下:
package com.test; import java.io.BufferedReader; import java.io.InputStreamReader; public class TestMain { public static void main(String[] args) throws Exception { PluginManager manager = new PluginManager();; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String cmd = br.readLine(); while(!cmd.equals("bye")){ if(cmd.startsWith("do")){ String pluginName = cmd.split(" ")[1]; manager.doSome(pluginName); } if(cmd.startsWith("load")){ String pluginName = cmd.split(" ")[1]; manager.loadPlugin(pluginName); } if(cmd.startsWith("unload")){ String pluginName = cmd.split(" ")[1]; manager.unloadPlugin(pluginName); } cmd = br.readLine(); } } }View Code
plugin-contract專案
Plugin.java
package com.test; public interface Plugin { public void doSome(); }
plugin-demo專案
Plugin1.java內容如下:
package com.test; public class Plugin1 implements Plugin{ public void doSome(){ System.out.println("Plugin1 doSome ... is I? YES."); } }
備註:
打包成 plugin-demo-1.0-SNAPSHOT.jar
Plugin1.java 內容1:System.out.println("Plugin1 doSome ... is I? YES."); 內容2:System.out.println("Plugin1 doSome ... is I? No.");