Java 带反射的模块化公共闭包原理
拥有这个maven项目结构Java 带反射的模块化公共闭包原理,java,maven,java-8,Java,Maven,Java 8,拥有这个maven项目结构 root pom ---> ModuleCore/pom.xml ---> ModuleA/pom.xml ---> ModuleB/pom.xml ---> ModuleC/pom.xml ---> ModuleD/pom.xml 其中模块A、B、C和D与模块Core有依赖关系,也就是说ModuleA与ModuleB有依赖关系,ModuleB与ModuleC有依赖关系 根据这种依赖性分
root pom
---> ModuleCore/pom.xml
---> ModuleA/pom.xml
---> ModuleB/pom.xml
---> ModuleC/pom.xml
---> ModuleD/pom.xml
其中模块A、B、C和D
与模块Core
有依赖关系,也就是说ModuleA
与ModuleB
有依赖关系,ModuleB
与ModuleC
有依赖关系
根据这种依赖性分布,我们同意:
如果我修改
ModuleCore
必须修改版本
ModuleA/pom.xml
ModuleB/pom.xml
ModuleC/pom.xml
ModuleD/pom.xml
ModuleA/pom.xml
ModuleB/pom.xml
如果我更新模块化
没有人必须更新版本
如果我更新ModuleC
必须修改版本
ModuleA/pom.xml
ModuleB/pom.xml
ModuleC/pom.xml
ModuleD/pom.xml
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());
}
}
@测试
void dependency with modulea(){
反射=新反射(“com.modulation.ccp”);
可选从问题的标签上看,这个问题似乎仅限于Java 8
查看JDK中内置的类。您可以在META-INF/package.MainA
文件中声明MainA
的实现-在每个ModuleA-D
jar中。然后查找这些实现:
ServiceLoader.load(MainA.class).iterator()
随着Java 9的出现,情况发生了一些变化。现在JDK9模块可以直接声明其服务,但它们仍然可以通过ServiceLoader
发现,因此这种方法也具有一定的前瞻性
显然,JDK之外还有很多解决方案,例如Spring有自动连接,或者ApplicationContext.getBeansOfType(类)
,Java EE有javax.enterprise.inject.Instance
,还有OSGi等等。为什么要消除模块之间的这些依赖关系?通常,当一个模块依赖于另一个模块时没有什么问题。当整个项目构建完成时,它们将被同步,不兼容的更改将立即可见。如果使用re事实上,一些隐藏的东西在运行时被破坏的风险很高,这比在构建过程中要烦人得多。基本上是以工具包模式交付独立的库。另外,对于模块中的小问题,我也在考虑SPI,目前还不确定。Spring方法需要在应用程序中引入Spring生态系统,至少至少是DI。我在寻找更具干扰性的解决方案,但是我会考虑你的所有建议。谢谢。