是否可以通过Java 9中的模块名称获取服务?

时间:2017-09-18 20:00:16

标签: java java-9 java-module

让我们考虑一下情况 - 有N个模块,所有模块都有相同接口的服务(com.foo.SomeService)。是否可以按模块名称(my.module)获取此服务,而无需迭代所有模块的所有服务?

2 个答案:

答案 0 :(得分:3)

我无法判断这是否是一个真实的问题。选择服务提供商的正确方法是探索其功能,这意味着设计一个良好的服务接口,以便消费者有足够的选择适当的实施。

如果这个问题是关于配置某些东西以使用特定的服务提供商,那么如果你真的需要,按模块名称选择是不难的:

ServiceLoader.load(service).stream()
        .filter(p -> "X".equals(p.type().getModule().getName()))
        .map(Provider::get)
        .findAny();

答案 1 :(得分:2)

ModuleDescriptor.Provides 可以提供模块提供的服务名称。

Module module; // representation for your 'my.module'
Set<ModuleDescriptor.Provides> provides = module.getDescriptor().provides();
provides.forEach(p -> {
    System.out.println("service - " + p.service());
    System.out.println("providers - " + p.providers());
});

例如如果模块声明如下:

module my.module {
    ...
    provides java.lang.reflect.AnnotatedElement with AnnotateElemenImpl; 
}

其中AnnotateElemenImpl类提供来自AnnotatedElement模块的接口java.lang.reflect的实现。上述共享代码段将返回详细信息:

service - java.lang.reflect.AnnotatedElement
providers - [com.module.AnnotateElemenImpl]