【问题标题】:How can I write my own plugin loader in java? [closed]如何在 java 中编写自己的插件加载器? [关闭]
【发布时间】:2011-11-27 02:08:50
【问题描述】:

如何在我的 java 程序中实现插件工具?

我正在使用 Java。我目前的项目与通用电子硬件有关,它有一个自定义命令集。

现在有一个通用的 GUI,人们可以通过它访问硬件。硬件在不同的环境中以不同的方式运行,即针对不同的客户端。现在的问题是 GUI 必须能够添加插件。插件意味着,它必须能够为拥有特权的客户提供特定的设施。从客户端来说,插件的添加很简单,就像点击一个按钮来添加一个特定的设施。

我之所以想到插件,是因为越来越多的工具只有在核心产品交付之后才会引入。

【问题讨论】:

    标签: java plugins add-on


    【解决方案1】:

    您可以随时向应用程序添加 jar 或插件。你不需要做任何特别的事情来实现这一点。

    如果您使用 OGSi,您可以更轻松地进行管理,支持同一 jar 的多个版本并在应用程序运行时将其删除。我建议看看 Apache Karaf + iPOJO

    【讨论】:

      【解决方案2】:

      您需要提供以下内容:

      • 创建一个 API,您的插件可以使用它来更改/扩展程序的行为(恕我直言,这是最棘手的部分)
      • 定义插件的公共入口,例如,定义插件入口点或扩展点的插件特定属性文件(实现接口的插件类的类名)李>
      • 从您选择的位置动态加载插件,例如,特定目录中的所有 *.jar 文件(查看URLClassLoader

      API 建议:

      • 更喜欢接口而不是(抽象)类
      • 这可能有助于帮助用户快速查看她可以实现哪些接口(例如IAction,注意前面的I)以及哪些接口由您的应用程序提供以供插件使用(例如WindowManager

      【讨论】:

        【解决方案3】:

        在任何面向对象语言中实现插件背后的主要思想是定义一组插件和相关类必须实现的通用接口,然后通过反射加载和实例化它们......

        您可以使用抽象工厂模式,以便可以实例化插件所需的任何对象...

        假设你的插件架构只有 3 个接口,每个插件必须提供实现这些接口的类,那么你的插件架构可能是这样的:

        public interface PluginInterfaceA {
        //Define API here
        };
        
        public interface PluginInterfaceB {
        // Define API here
        };
        
        public interface PluginInterfaceC {
        // Define API here
        };
        
        public interface PluginFactory {
        /**
         * Creates plugin A object.
         */
        PluginInterfaceA createPluginA();
        /**
         * Creates plugin B object.
         */
        PluginInterfaceB createPluginB();
        /**
         * Creates plugin C object.
         */
        PluginInterfaceC createPluginC();
        };
        

        然后让插件在一个 XML 文件或属性文件中为插件定义插件工厂的类名:

        例如,假设您的插件定义:

        package com.my.plugin;
        
        public class PluginAImpl implements PluginInterfaceA {
        // Code for the class
        };
        
        public class PluginBImpl implements PluginInterfaceB {
        // Code for the class
        };
        
        public class PluginCImpl implements PluginInterfaceC {
        // Code for the class
        };
        
        public class PluginFactoryImpl implements PluginFactory {
        public PluginInterfaceA createPluginA() {
          return new PluginAImpl();
        }
        public PluginInterfaceB createPluginB() {
          return new PluginAImpl();
        }
        public PluginInterfaceC createPluginC() {
          return new PluginAImpl();
        }
        };
        

        然后在属性文件中定义 // 插件的plugin.jar中提供的文件plugin.properties plugin.factory.class= com.my.plugin.PluginFactoryImpl;

        在你的应用中可以做到

        Properties properties = new Properties();
        properties.load(this.getClass().getClassLoader().getResourceAsStream("plugin.properties"));
        
        String factoryClass = properties.get("plugin.factory.class");
        
        PluginFactory factory = Class.forName(factoryClass);
        
        PluginInterfaceA interfaceA = factory.createPluginA();
        PluginInterfaceB interfaceB = factory.createPluginB();
        PluginInterfaceC interfaceC = factory.createPluginC();
        

        // 这里调用你喜欢的创建的类。

        谢谢 巴勃罗

        【讨论】:

        • 假设他想提供一个新插件,可以是PluginAImpl 的扩展或全新的。PluginFactoryImpl 如何在不修改代码的情况下知道它?
        • 我的意思是这些接口是用于一种插件的类并且是相关的,例如图形编辑器想要支持新形状,为此我需要为形状提供接口,调色板中工具的界面 另一个用于 UI 上的按钮。这些接口中的每一个都与插件相关,因此抽象工厂创建相关类的组,然后我提供我的工厂来创建我的实现。在我的示例中,PluginInterfaceA、PluginInterfaceB、PluginInterfaceC 是同一个插件的一部分,并且完全符合插件。
        • 这是我的观点。您需要为每个新实现修改工厂
        • 谢谢Pablo...我正在尝试这个...
        • 不,实际上你不必为插件的每个实现修改工厂,我实际上将我的应用程序编码为一组具有明确定义的接口的抽象,并让每个插件供应商为我的应用程序来开发实现,所以当另一个供应商想要添加插件时,我的代码不会改变,只需使用反射实例化供应商的工厂并使用工厂的接口为插件的每个组件创建抽象。
        【解决方案4】:

        JAR 文件格式有its own little system for managing plugins,用于Java SE 的几个部分,包括JDBC 驱动程序管理。只需定义一个服务接口,将带有实现的 JAR 文件放在类路径中,然后使用 ServiceLoader.load 加载实现。

        【讨论】:

          猜你喜欢
          • 2010-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-06
          • 1970-01-01
          • 2012-10-10
          • 1970-01-01
          相关资源
          最近更新 更多