gpt4 book ai didi

java - SPI + JDK 9 + 模块信息.java

转载 作者:搜寻专家 更新时间:2023-10-31 20:17:18 24 4
gpt4 key购买 nike

我正在 JDK 9 上试验 SPI。整个示例在没有“module-info.java”的情况下适用于 JDK 9。添加“module-info.java”后,ServiceLocator 未找到实现类。我很困惑,我在模块化的 JDK 9 项目中找不到有效的 SPI 示例。

所以我的示例项目如下所示:

/spidemo
├── apiModule
│   ├── pom.xml
│   └── src
│   └── main
│   └── java
│   ├── eu
│   │   └── com
│   │   └── example
│   │   └── text
│   │   └── spi
│   │   └── TextAPI.java
│   └── module-info.java
├── applicationB
│   ├── pom.xml
│   └── src
│   └── main
│   ├── java
│   │   └── eu
│   │   └── com
│   │   └── example
│   │   └── spi
│   │   └── b
│   │   └── application
│   │   └── DemoB.java
│   └── module-info.java
├── applicationCommon
│   ├── pom.xml
│   └── src
│   └── main
│   └── java
│   ├── eu
│   │   └── com
│   │   └── example
│   │   └── spi
│   │   └── application
│   │   └── TextAPIProvider.java
│   └── module-info.java
├── implementationB
│   ├── pom.xml
│   └── src
│   └── main
│   ├── java
│   │   └── eu
│   │   └── com
│   │   └── example
│   │   └── implb
│   │   └── text
│   │   └── TextB.java
│   ├── module-info.java
│   └── resources
│   └── META-INF
│   └── services
│   └── eu.com.example.text.spi.TextAPI

我已经介绍了界面:

package eu.com.example.text.spi;
public interface TextAPI {
String getHelloWorldText();
}

此接口(interface)由以下人员实现:

package eu.com.example.implb.text;
import eu.com.example.text.spi.TextAPI;
public class TextB implements TextAPI {
public String getHelloWorldText() {
return "Text from B implementation";
}
}

通过类似于以下的代码搜索实现:

package eu.com.example.spi.application;
import eu.com.example.text.spi.DefaultTextAPI;
import eu.com.example.text.spi.TextAPI;
import java.util.ServiceLoader;
public class TextAPIProvider {

public static TextAPI getProvider(String providerName) {
ServiceLoader<TextAPI> serviceLoader = ServiceLoader.load(TextAPI.class);
for (TextAPI provider : serviceLoader) {
String className = provider.getClass().getName();
if (providerName.equals(className)) {
return provider;
}
}
throw new RuntimeException(providerName + " provider is not found!");
}
}

现在是有趣的部分。当我在没有执行下面的类(class)时:

  • /implementationB/src/main/java/module-info.java
  • /applicationB/src/main/java/module-info.java

然后找到实现类并打印出文本。

package eu.com.example.spi.b.application;
import eu.com.example.spi.application.TextAPIProvider;
public class DemoB {
public static void main(String[] args) {
System.out.println("---> " + TextAPIProvider.getProvider("eu.com.example.implb.text.TextB").getHelloWorldText());
}
}

引入这两个“module-info.java”文件后,ServiceLocator没有找到实现类。/applicationB/src/main/java/module-info.java 的内容:

module eu.com.example.applicationB {
requires eu.com.example.apiModule;
requires transitive eu.com.example.applicationCommon;
uses eu.com.example.text.spi.TextAPI;
}

/implementationB/src/main/java/module-info.java 的内容:

module eu.com.example.implb.text {
requires eu.com.example.apiModule;
exports eu.com.example.implb.text;
// provides eu.com.example.implb.text.TextB with eu.com.example.text.spi.TextAPI;
}

当我取消注释时:

provides eu.com.example.implb.text.TextB with eu.com.example.text.spi.TextAPI;

然后出现编译错误的行:

.../implementationB/src/main/java/module-info.java:[7,74] the service implementation type must be a subtype of the service interface type, or have a public static no-args method named "provider" returning the service implementation
.../implementationB/src/main/java/module-info.java:[7,5] service implementation must be defined in the same module as the provides directive

我曾尝试根据编译错误提示更改包名称,但后来我引入了“拆分包”问题。

要在完全模块化的 JDK 9 中使用 ServiceLocator,我应该怎么做?是否可以?有没有人看过工作示例?代码也可以在这里看到:https://github.com/RadoslawOsinski/spidemo

最佳答案

您可以更改为使用:-

provides eu.com.example.text.spi.TextAPI with eu.com.example.implb.text.TextB; 
// you provide a service through its implementation

代替

provides eu.com.example.implb.text.TextB with eu.com.example.text.spi.TextAPI; 

Services 文档中提供了有关实现的示例。

关于java - SPI + JDK 9 + 模块信息.java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46632187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com