在Java中动态加载模块(类)的最佳方法

我目前正在编写一个需要在不同类型的设备上运行的应用程序。 我的方法是创建一个“模块化”应用程序,它可以根据操作所需的设备动态加载不同的类。

为了使应用程序易于扩展,我的目标是为其他模块(.jar或.class文件)分配一个特定的路径,保留核心程序。 当不同的客户需要不同的模块时(这不需要为每个模块编译不同的应用程序),这将是至关重要的。

这些模块将实现一个通用接口,而“核心”应用程序可以使用接口上定义的这些方法,让单个实现完成工作。 根据需要加载它们的最佳方法是什么? 我正在考虑使用URLClassLoader,但我不知道这种方法是否是根据新的模式和Java趋势是最新的,因为我想避免设计糟糕的应用程序和弃用的技术。 使用JDK 9制作模块化且易于扩展的应用程序的另一种最佳方法是什么 (可以通过将模块文件添加到文件夹来扩展)?

听起来你可能想要使用自Java 6以来一直可用的ServicerLoader接口。但是,请记住,如果你想使用Springdependency injection,这可能不是你想要的。

除了@SeverityOne给出的ServicerLoader用法之外,您还可以使用module-info.java使用“uses”/“provide”关键字来声明接口的不同实例。

然后使用模块路径而不是类路径,它加载包含模块的所有目录,不需要创建特定的classLoader

serviceLoader用法:

 public static void main(String[] args) { ServiceLoader sl = ServiceLoader.load(IGreeting.class); IGreeting greeting = sl.findFirst().orElseThrow(NullPointerException::new); System.out.println( greeting.regular("world")); } 

在用户项目中:

 module pl.tfij.java9modules.app { exports pl.tfij.java9modules.app; uses pl.tfij.java9modules.app.IGreeting; } 

在提供者项目中:

 module pl.tfij.java9modules.greetings { requires pl.tfij.java9modules.app; provides pl.tfij.java9modules.app.IGreeting with pl.tfij.java9modules.greetings.Greeting; } 

最后是CLI用法

 java --module-path mods --module pl.tfij.java9modules.app 

这是一个例子; Github示例 (感谢“tfij /”存储库初始示例 )

编辑,我意识到存储库已经提供了解耦示例: https : //github.com/tfij/Java-9-modules—reducing-coupling-of-modules