对 java 9 ServiceLoader::load 方法以及如何提供服务的方式感到困惑 impl

Confused about java 9 ServiceLoader::load method and the way how to provide a service impl

在此 java 文档中: https://docs.oracle.com/javase/9/docs/api/java/util/ServiceLoader.html Deploying service providers as modules 一章,它说:

com.example.impl.ExtendedCodecsFactory is a public class that does not implement CodecFactory, but it declares a public static no-args method named "provider" with a return type of CodecFactory.

但事实是我不能使用 provides...with 来提供服务实现,如果不实现服务,它会抛出编译错误和运行时错误。

我是否可以提供一个 public 静态提供程序方法,并且我可以在不在模块信息文件中定义 provides...with 的情况下提供服务实现? 困惑,希望有人能帮助。

只要带有提供程序方法的 class 在模块中结束,就可以正常工作。我刚刚创建了 a small demo project 显示:

// 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

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

最接近的是上面的部分:

Deploying service providers as modules

[...]

A service provider that is deployed as an automatic module on the application module path must have a provider constructor. There is no support for a provider method in this case.

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