• Java插件式开发 动态加载Jar


    背景

    为了项目的扩展性,很多项目往往都会使用插件的方式为项目增加新功能,比如开发某种聊天机器人,增加扩展功能。这种方式非常灵活而且比较容易开发,本文就简单探讨一下Java如何动态加载Jar实现插件化开发。

    规范或协议

    在开始之前,首先需要定义一种规范,加载插件后如何调用插件内的方法,如何获取插件的名称版本号等信息。

    如果有开发过安卓的Xposed插件应该知道,Xposed插件需要添加一个xposed_init文件,内容为入口类全名。

    本文只是做个简单的演示,具体实现方式可以不同

    此处我们定义plugin.properties作为插件的入口,加载jar后,读取mainClass的值作为入口类,版本号等信息可以自行添加,此处省略。

    一般情况下,插件和项目都会依赖同一个库,插件去实现库中的接口或继承抽象类,项目加载插件调用方法,不过此处就不做演示。

    编写插件

    简单编写一个打印传入内容的插件

    入口类

    package cn.montaro.plugins;
    
    public class Test {
        public void print(String text) {
            System.out.println("我是插件我被调用了");
            System.out.println(text);
        }
    }
    

    plugin.properties文件

    mainClass=cn.montaro.plugins.Test
    

    image

    打包成jar

    编写插件加载器

    package cn.montaro.loader;
    
    import java.io.File;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.*;
    import java.util.Properties;
    
    public class PluginLoader {
    
        private final static String PROPERTIES_NAME = "plugin.properties";
        private final static String MAIN_CLASS = "mainClass";
    
        /**
         * 加载jar文件
         *
         * @param jarFilePath jar文件路径
         * @return
         * @throws IOException
         * @throws ClassNotFoundException
         */
        public static Class loadJar(String jarFilePath) throws IOException, ClassNotFoundException {
            ClassLoader classLoader = getClassLoader(jarFilePath);
            Properties properties = getProperties(classLoader, PROPERTIES_NAME);
            String mainClass = properties.getProperty(MAIN_CLASS);
            return loadClass(classLoader, mainClass);
        }
    
        /**
         * 获得ClassLoader
         *
         * @param jarFilePath jar文件路径
         * @return
         * @throws MalformedURLException
         */
        private static final ClassLoader getClassLoader(String jarFilePath) throws MalformedURLException {
            File jarFile = new File(jarFilePath);
            if (!jarFile.exists()) {
                return null;
            }
            URL url = jarFile.toURI().toURL();
            URLClassLoader classLoader = new URLClassLoader(new URL[]{url}, null);
            return classLoader;
        }
    
        /**
         * 获得jar中的properties
         *
         * @param classLoader    classLoader
         * @param propertiesName 文件名称
         * @return
         * @throws IOException
         */
        private static Properties getProperties(ClassLoader classLoader, String propertiesName) throws IOException {
            InputStream propertiesStream = classLoader.getResourceAsStream(propertiesName);
            Properties properties = new Properties();
            properties.load(propertiesStream);
            return properties;
        }
    
        /**
         * 加载类
         *
         * @param classLoader classLoader
         * @param className   全类名
         * @return
         * @throws ClassNotFoundException
         */
        private static Class loadClass(ClassLoader classLoader, String className) throws ClassNotFoundException {
            Class<?> clazz = classLoader.loadClass(className);
            return clazz;
        }
    
    }
    
    

    加载插件

    将插件打包成jar

    public class Main {
        public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
            String jarFilePath = "D:\\Projects\\plugin-test\\target\\plugin-test-1.0-SNAPSHOT.jar";
            Class mainClass = PluginLoader.loadJar(jarFilePath);
            Object o = mainClass.newInstance();
            Method print = mainClass.getDeclaredMethod("print", String.class);
            print.invoke(o, "23333");
        }
    }
    

  • 相关阅读:
    spring cloud 搭建(服务)
    spring cloud 搭建(配置中心)
    spring cloud 搭建(注册中心)
    spring cloud 搭建
    skywalking 配置和使用(windows)
    jenkins 发布报错
    web 显示 pdf
    springmvc Cacheable 不设置key
    iRed邮箱使用情况
    关闭SSL服务[iRedMail]
  • 原文地址:https://www.cnblogs.com/montaro/p/15714116.html
Copyright © 2020-2023  润新知