提问者:小点点

对java9 ServiceLoader::加载方法以及如何提供服务的方法感到困惑


在java文档:https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html将服务提供者部署为模块一章中,它说:

com. example.inl.ExtendedCodecsFactory是一个不实现CodecFactory的公共类,但它声明了一个名为“Provider”的公共静态无参数方法,返回类型为CodecFactory。

但事实是我不能使用提供… with来提供服务实现,它会在不实现服务的情况下引发编译错误和运行时错误。

有没有可能我提供了一个公共的静态提供者方法,我可以提供一个服务实现,而无需在module-info文件中使用提供…?困惑,希望有人能帮忙。


共1个答案

匿名用户

只要具有提供者方法的类最终出现在一个模块中,这就可以正常工作。我刚刚创建了一个小型演示项目,显示:

// MODULE com.example.codec.api

public interface CodecFactory { }

module com.example.codec.api {
    exports com.example.codec;
    uses com.example.codec.CodecFactory;
}


// MODULE com.example.codec.impl

public class ExtendedCodecsFactory {

    public static CodecFactory provider() {
        return new CodecFactory() { };
    }

}

module com.example.codec.impl {
    requires com.example.codec.api;
    provides com.example.codec.CodecFactory
        with com.example.impl.ExtendedCodecsFactory;
}

要编译:

javac
    -d classes/com.example.codec.api
    src/com.example.codec.api/module-info.java
    src/com.example.codec.api/com/example/codec/CodecFactory.java
javac
    -p classes/com.example.codec.api
    -d classes/com.example.codec.impl
    src/com.example.codec.impl/module-info.java
    src/com.example.codec.impl/com/example/impl/ExtendedCodecsFactory.java

如果您试图创建一个不在模块中的服务提供者,提供者方法将不起作用。不幸的是,留档在这方面并不十分清楚。在类路径上部署服务提供者部分既没有提到提供者构造函数,也没有提到提供者方法,事实上它甚至没有提到继承。

你得到的最接近的是在上面的部分:

[...]

在应用程序模块路径上部署为自动模块的服务提供者必须具有提供者构造函数。在这种情况下不支持提供者方法。

这包括将不带模块描述符的普通JAR放到模块路径上。