有了这个maven项目结构
root pom
---> ModuleCore/pom.xml
---> ModuleA/pom.xml
---> ModuleB/pom.xml
---> ModuleC/pom.xml
---> ModuleD/pom.xml其中模块A, B, C and D与模块Core有依赖关系,也假设ModuleA与ModuleB有依赖关系,ModuleB与ModuleC有依赖关系。
对于这种依赖分布,我们同意:
如果我修改
ModuleCore必须进行版本设置
ModuleA/pom.xml
ModuleB/pom.xml
ModuleC/pom.xml
ModuleD/pom.xml如果我更新ModuleD,没有人需要更新版本。
如果我更新ModuleC
必须进行版本设置
ModuleA/pom.xml
ModuleB/pom.xml好了,在整个解释之后,我想要实现的是模块之间没有相互依赖关系,而只是与ModuleCore相关
我第一次尝试是将接口创建为协定,以便在模块之间通信,并将协定放在moduleCore中,然后通过reflection在classpath中查找接口的实现并调用来调用实现。但我觉得倒影看起来很粗糙,
谁能给我一些建议,如何应用公共闭包原则,而不是将所有代码都移到ModuleCore中,并使其成为一个整体?
我使用反射的第一种方法的代码示例。
@Test
void dependencyWithModuleA() {
Reflections reflections = new Reflections("com.modularization.ccp");
Optional<Optional<?>> any = reflections.getSubTypesOf(MainA.class)
.stream()
.map(clazz -> {
try {
MainA mainA = clazz.newInstance();
return Optional.of(mainA.main());
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return Optional.empty();
}).findAny();
if (any.isPresent() && any.get().isPresent()) {
System.out.println(any.get().get());
}
}重要的是要澄清它将在服务启动时完成的反射调用,以及它将使用单例模式保存的实例引用,以避免性能问题。
请对此方法的所有批评,它将是非常欢迎的。
致以问候。
发布于 2018-04-09 00:14:52
从问题上的标签来看,这个问题似乎仅限于Java 8。
看一下内置在JDK中的ServiceLoader类。您可以在META-INF/package.MainA文件中声明MainA的实现-在每个ModuleA-D jars中。然后找到这些实现:
ServiceLoader.load(MainA.class).iterator()在Java 9中,情况发生了一些变化。现在,JDK9模块可以直接声明它的服务,但仍然可以通过ServiceLoader发现它们,因此这种方法也具有一定的未来校验性。
显然,在JDK之外也有相当多的解决方案,例如Spring有自动装配,或者ApplicationContext.getBeansOfType(Class),Java有javax.enterprise.inject.Instance,还有OSGi,等等。
https://stackoverflow.com/questions/49699472
复制相似问题