如何使Java应用程序模块化

时间:2015-08-05 15:23:21

标签: java spring javafx

我正在努力使我的Java应用程序模块化,以便客户端将拥有核心基础模块,但是他/她将能够在它们出现时添加其他功能/插件,或者随着她的需求扩展。就像NetBeans这样的IDE一样。

我计划在客户端pc中有一个名为modules / plugins的子目录,其中任何插件应用程序将作为.jar文件包含在内。当用户启动应用程序时,主模块将在最终项目中包含这些其他插件,因此,例如,Stage将具有来自主模块和插件模块的按钮{{3 }}

我精通scene,使用视图执行此操作。借用这个,我可以有一个HBox,例如在启动应用程序时从不同插件中填充Buttons的主模块上。

如何让core_base_module.jar调用下面的plugins目录中的所有插件。换句话说,如何让一个.jar文件调用另一个.jar文件?

示例目录结构:

main dir/---core_base_module.jar
        /---plugins ---/chat.jar
                       /videoplayer.jar
                       /like.jar
                       /unlike.jar
                       /etc.jar
                       /etc_etc.jar

2 个答案:

答案 0 :(得分:4)

您可以通过以下方式手动执行此操作:

  1. 查找插件文件夹
  2. 扫描文件夹以获取所有罐子的列表
  3. 创建一个类加载器,连接jar文件,然后在每个jar中查看插件API接口的实现。
  4. 创建一个实例,并在插件注册表中注册
  5. 虽然您可以自己完成所有操作,但使用Service Loader API可能会更容易。此API是Java的一部分,是为此目的而创建的。这是spring用来加载可以处理spring XML配置文件中的不同XML标记的插件。例如,查看spring-web.jar!/META-INF/services

    然后你会希望你的启动脚本将所有JAR添加到主类路径中,如下所示:

    java -cp plugins/* -jar app.jar
    

    或者如果你没有lauch脚本,你可以在java中做同样的事情,但创建一个URLClassLoader传递你想要的所有jar文件,然后在这个新的类加载器中调用你的主类。 / p>

    更多信息:

答案 1 :(得分:1)

如果您真的想要创建专业级应用程序,@ David Roussel建议的ServiceLoader API是您的选择。

如果你喜欢更轻量级的东西,你可以手工,你可以只使用一个API包,其中只包含你在应用程序中包含的抽象类接口,以及一个包含实际的实现包您作为单独的jar提供的类。由于您无法通过new通过接口创建对象,因此您必须使用工厂模式和反射。您还应该使用Class.forName("package.to.class")来测试程序开头的实施存在。

示例假设接口Foo可选地由FooImpl实现,其构造函数采用工厂可能的字符串参数:

public class FooFactory {
    public static final String CLASSNAME = "...FooImpl";
    public static Foo createFoo(String key) {
        try {
            Class<?> fooclazz = Class.forName(CLASSNAME);
            Foo foo = (Foo) fooclazz.getConstructor(String.class).newInstance(key);
            return foo;
        }
        catch (Exception e) {
            // eventually process some exceptions
        }
        return null;
    }
}

您最初使用以下命令设置全局布尔值hasFoo(主类的静态成员):

    try {
        Class.forName(FooFactory.CLASSNAME);
        hasOpt = true;
    }
    catch (Exception e) {
        hasOpt = false;
    }

你可以选择使用它:

    if (MainClass.hasOpt) {
        Foo foo = FooFactory.createFoo("bar");
        // do something with foo
    }
    else {
        // warning message : Option not present
    }

使用此方法,只需在类路径中添加实现jar并重新启动应用程序即可使用它。