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