JDK 9에서 SPI를 실험하고 있습니다. 전체 예제는 "module-info.java"없이 JDK 9에서 작동합니다. "module-info.java"를 추가 한 후 ServiceLocator가 구현 클래스를 찾지 못합니다. 혼란스러워서 modulerized JDK 9 프로젝트에서 SPI 예제를 찾을 수 없습니다.SPI + JDK 9 + module-info.java
/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.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.text.spi;
public interface TextAPI {
String getHelloWorldText();
}
이 인터페이스에 의해 구현되는
그래서 내 예제 프로젝트는 다음과 같습니다 유사하게 :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!");
}
}
이제 재미있는 부분입니다. 내가없이 아래 클래스를 실행하고 있습니다 :
- /implementationB/src/main/java/module-info.java
- /applicationB/src/main/java/module-info.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());
}
}
은 ServiceLocator에서 찾을 수 없습니다. /applicationB/src/main/java/module-info.java의 내용 : /implementationB/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;
}
내용 :
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이
당신이'eu.com.example.text.spi.TextAPI에 eu.com.example.implb.text를 제공한다고 추가한다고 가정합니다.TextB'는 TextB로 구현 (서비스 유형 아님)입니다. –
대단히 감사합니다! 나는이 오타에 몇 시간을 소비했다. 그게 내 문제를 해결해 줬어. –