我正在为一个包含几个Maven模块的库编写扩展。我需要在一个模块的顶部添加一些功能,但不想添加不必要的依赖关系,以防有人想在没有我的扩展的情况下使用该模块(典型的用例)。
我能想到的一个解决方案是使用扩展名创建另一个模块,并尝试使用反射从其类中调用方法。会有这样的检查:
try {
Class.forName("my.package.Foo", false, getClass().getClassLoader());
// extension will be enabled and some method will be called using reflection
} catch(ClassNotFoundException e) {
// extension will be disabled
}
并且仅当该类在classpath上时才调用该方法。如果您在其模块上添加了Maven依赖关系(除了对其扩展模块的依赖关系),那么可以激活该扩展。
但这听起来并不是最好的方法。有没有更优雅的解决方案来解决这个问题?
一种方法是使用内置的服务提供商接口(SPI)。
基本思想是使您的可选库提供某些接口(“服务”)的实现,这些接口可以在主应用程序中轻松找到。看这个例子
// scan classpath for all registered
// implementations of Module interface
ServiceLoader<Module> loader = ServiceLoader.load(Module.class);
for (Module module : loader) {
module.doSomething();
}
一旦您的可选依赖项在类路径中,服务加载程序便会找到它。
在Oracle的“创建可扩展的应用程序”教程中,您可以找到许多有关如何制作它的示例。
另一种方法是使用依赖注入框架,例如spring或google guice。这些框架还提供了用于自动组件发现的类路径扫描机制。这种解决方案比更加灵活,但更重SPI
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句