Java 获取使用ServiceLoader提供多个服务的服务提供程序类的同一实例

Java 获取使用ServiceLoader提供多个服务的服务提供程序类的同一实例,java,serviceloader,Java,Serviceloader,我有个问题,我不知道该怎么办 假设我有两个服务提供者接口(SPI) 以及提供两种服务的服务提供商,即 public class LogView implements View, Logger{ ... } 问题是,当我试图通过ServiceLoader.load(Logger.class)获取日志服务实例时,它与使用ServiceLoader.load(View.class)创建的实例不同。有没有一种方法可以让我从两个调用中获得相同的对象实例 其思想是,在将视图加载为GUI之后,我希望

我有个问题,我不知道该怎么办

假设我有两个服务提供者接口(SPI)

以及提供两种服务的服务提供商,即

public class LogView implements View, Logger{
    ...
}
问题是,当我试图通过
ServiceLoader.load(Logger.class)
获取日志服务实例时,它与使用
ServiceLoader.load(View.class)
创建的实例不同。有没有一种方法可以让我从两个调用中获得相同的对象实例


其思想是,在将视图加载为GUI之后,我希望能够登录到同一个GUI实例,而不是另一个实例。目前,我只能使用两个独立的实例,因此日志确实会显示出来。

一个与Java模块一起添加的解决方案,但需要注意的是,它只适用于显式模块,即模块信息中的服务声明,而不是
META-INF/services
中的文件

然后,您可以声明一个
public static T provider()
方法来代替公共默认构造函数,而返回类型
T
必须可分配给服务类型。当这样一个方法被声明时,声明类型不需要是
t
本身的一个实现,但如果是,它就不是一个错误

所以给出了类声明

package somemodule;

public interface Logger{
    void log(String s);
}
和一个模块声明,如

module SomeModule {
    uses somemodule.Logger;
    uses somemodule.View;

    provides somemodule.Logger with somemodule.LogView;
    provides somemodule.View with somemodule.LogView;
}
以下代码打印
true

View v = ServiceLoader.load(View.class).findFirst().orElseThrow();
Logger l = ServiceLoader.load(Logger.class).findFirst().orElseThrow();
System.out.println(v == l);
package somemodule;

public class LogView implements View, Logger {
    static final LogView INSTANCE = new LogView();
    private LogView() {}

    public static LogView provider() {
        return INSTANCE;
    }

    @Override
    public void display() {
        System.out.println("display");
    }

    @Override
    public void log(String s) {
        System.out.println("log "+s);
    }

}
module SomeModule {
    uses somemodule.Logger;
    uses somemodule.View;

    provides somemodule.Logger with somemodule.LogView;
    provides somemodule.View with somemodule.LogView;
}
View v = ServiceLoader.load(View.class).findFirst().orElseThrow();
Logger l = ServiceLoader.load(Logger.class).findFirst().orElseThrow();
System.out.println(v == l);