1. 今日、Java の spi の考え方を学んでいたときに、自分でデモを書いたのですが、spi の実装クラスが見つからないことがわかりました。コードは次のとおりです。
package com.fwkily.spi;
public interface Search {
void search();
}
package com.fwkily.spi;
public class ElasticSearch implements Search {
@Override
public void search() {
System.out.println("通过elasticsearch搜索!");
}
}
package com.fwkily.spi;
public class MysqlSearch implements Search {
@Override
public void search() {
System.out.println("通过mysql搜索!");
}
}
テストクラス:
package com.fwkily.spi;
import java.util.Iterator;
import java.util.ServiceLoader;
public class Main {
public static void main(String[] args) {
ServiceLoader<Search> loader = ServiceLoader.load(Search.class);
Iterator<Search> iterator = loader.iterator();
while (iterator.hasNext()){
iterator.next().search();
}
}
}
このインターフェイスの実装クラスを com.fwkily.spi.Search ファイルに記述します。
com.fwkily.spi.MysqlSearch
ディレクトリ構造:
ただし、main メソッドが実装クラスの情報を出力できないことが判明しました。
確認したところ、META-INF/servicesディレクトリをクラスパス配下に置く必要があり、META-INF/servicesをresourcesディレクトリに置くだけなので、ディレクトリ構成を以下のように修正します。
再度正常に実行します。
chatgpt は次のように答えました。
SPI の実装クラスが見つからない場合は、いくつかの解決策が考えられます。
-
クラスパスが正しいかどうかを確認します。SPI を使用する場合、実装クラスの jar パッケージをクラスパスに配置する必要があります。そうしないと、対応する実装クラスが見つかりません。
-
META-INF/services ディレクトリが正しいかどうかを確認します。SPI を使用する場合、実装クラスは META-INF/services ディレクトリにインターフェイスの完全修飾名にちなんだ名前のファイルを作成する必要があり、ファイル内の各行に実装クラス名の完全修飾名。実装クラスがファイル内に正しく配置されていない場合、実装クラスが見つからないこともあります。ファイルは UTF-8 でエンコードされている必要があり、BOM ヘッダーを含めることはできないことに注意してください。
-
実装クラスの命名規則を確認します。SPI を使用する場合、実装クラスの命名規則にはインターフェイス名の接頭辞が必要であり、パブリックで引数のないコンストラクターである必要があります。
-
org.springframework.boot.autoconfigure.EnableAutoConfiguration
実装クラスが特定の場所にあるかどうかを確認する: 一部のフレームワークまたはライブラリでは、実装クラスを特定の場所に配置する必要があると指定されている場合があります。たとえば、Spring Boot はデフォルトでパス内の実装クラスをスキャンします。