基于SPI的Java插件技术-加载指定插件

admin 2024年9月28日15:14:28评论16 views字数 1868阅读6分13秒阅读模式

之前的文章《基于SPI的Java插件技术》有说这里的缺点:

“虽然ServiceLoader也算是使用的延迟加载,但是基本只能通过遍历全部获取,也就是接口的实现类全部加载并实例化一遍。如果你并不想用某些实现类,它也被加载并实例化了,这就造成了浪费。获取某个实现类的方式不够灵活,只能通过Iterator形式获取,不能根据某个参数来获取对应的实现类。”

今天吃饭的时候突然想到,我单独指定个地址不就好了,说干就干,也不是很复杂,写个json文件,用来指定插件名、插件地址:

 {
   "Plugin1": {
     "address": "plugins/Plugin1.jar"
  },
   "Plugin2": {
     "address": "plugins/Plugin2.jar"
  }
 }

其实这里也可以存数据库、用properties写配置、用yaml写配置都行,爱怎么弄怎么弄,我这里做个测试,就写json了。写个根据文件名加载指定插件的方法:

   public IPluginService loadPlugin(String pluginName) throws Exception {
         IPluginService pluginService = null;
         // 获取 JSON 文件的输入流
         InputStream inputStream = JSONReader.class.getResourceAsStream("/plugin.json");
 
         String jsonText = null;
         jsonText = IOUtils.toString(inputStream, "UTF-8");
 
         // 使用 FastJSON 解析 JSON 字符串
         JSONObject jsonObject = JSON.parseObject(jsonText);
 
         // 可以使用 jsonObject 获取数据
         JSONObject jsonPlugin = jsonObject.getJSONObject("Plugin1");
         String address=jsonPlugin.getString("address");
         // 关闭输入流
         inputStream.close();
 
         URL[] urls = new URL[]{new URL("file:" +address)};
         URLClassLoader urlClassLoader = new URLClassLoader(urls);
         ServiceLoader<IPluginService> serviceLoader = ServiceLoader.load(IPluginService.class, urlClassLoader);
         return serviceLoader.iterator().next();
    }

注释已经写得很清晰了,文章也就不用记了,当然我们用来测试的主程序也需要改一下:

 public static void main(String[] args) throws MalformedURLException {
         System.out.println("开始加载插件");
         PluginLoader pluginLoader = new PluginLoader();
         IPluginService service = null;
         try {
             service = pluginLoader.loadPlugin("Plugin1");
        } catch (Exception e) {
             e.printStackTrace();
        }
         System.out.println("插件加载成功n");
 
 
         System.out.println("===插件===");
         System.out.println("插件名:" + service.name());
         System.out.println("版本号:" + service.version());
         System.out.println("插件服务启动:");
         service.service();
 
    }

运行一下看下效果:

基于SPI的Java插件技术-加载指定插件

emmm,没啥毛病,程序已经放到github上,不得不说的是,今天一遍过,没有需要debug

原文始发于微信公众号(天幕安全团队):基于SPI的Java插件技术-加载指定插件

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月28日15:14:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   基于SPI的Java插件技术-加载指定插件https://cn-sec.com/archives/1977110.html

发表评论

匿名网友 填写信息