zoukankan      html  css  js  c++  java
  • 热加载卸载jar包

    热加载卸载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中
     * @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
    "+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;
        }
    }
    View Code

    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.");

    3 执行演示

     

    参考:

    [1]  jar包 热加载/卸载 的初步实现 

  • 相关阅读:
    EOS之session的数据获取
    c# 数据库操作之ACCESS
    基础之创建与导出
    dotNET5的MVC页面传值方式总结
    dotNET开发之MVC中Controller返回值类型ActionResult方法总结
    C# 计算农历日期方法(2021版)
    普通邮箱设置客户端授权码并开启stmp服务以及关于QQ邮箱“命令顺序不正确。 服务器响应为:Error: need EHLO and AUTH first !”问题全指导
    13 张图,深入理解 Synchronized
    Springboot 注解大全
    python中的print()函数的学习-1
  • 原文地址:https://www.cnblogs.com/Ming8006/p/14208291.html
Copyright © 2011-2022 走看看