在Java9 中是否可以通过模块名称获取服务?

Is it possible to get service by module name in Java 9?

让我们考虑一下这种情况——有 N 个模块,它们都具有相同接口的服务 (com.foo.SomeService)。是否可以通过模块名称(my.module)获取此服务而不需要迭代所有模块的所有服务?

ModuleDescriptor.Provides可以提供Module提供的服务名称

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 class 提供 java.lang.reflect 模块的接口 AnnotatedElement 的实现。上面的共享代码段将 return 详细信息为:

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

我不知道这是否是一个真正的问题。 select 服务提供者的正确方法是探索其能力,这意味着设计一个良好的服务接口,以便消费者有足够的能力 select 适当的实现。

如果这个问题是关于配置某些东西以使用特定服务提供商的,那么如果您确实需要 select 通过模块名称并不难:

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