JAva SPI 01-SPIは何ですか?spi使用入門チュートリアルServiceLoader使用概要
4921 ワード
シリーズディレクトリ
spi 01-spiとは何ですか?使用開始
spi 02-spiの実戦解決slf 4 jパケット衝突問題
spi 03-spi jdkソースコード解析を実現
spi 04-spi dubboソースコード解析を実現
spi 05-dubbo adaptive extension適応拡張
spi 06-自分でゼロから手書きでSPIフレームワークを実現
spi 07-自動生成SPIプロファイル実装方式
問題の導入
以前は、この基準に従って実現させるための基準を指定し、対応する容器を作成したいと思っていました.
その後、コードでこれらの実装を動的に取得し、コードを実行します.
困難
インタフェースの実装をどのように取得しますか?
初歩案
同僚と議論するのは、パッケージのclassをスキャンする方法です.次に、カスタム基準のサブクラスであるかどうかを判断します.欠点 違和感を感じ,デッドインプリメンテーションクラスのパッケージ名を限定する必要があり,性能も劣る.
SPIの解決方法
今日はhibernate-validatorソースコードを読んで啓発されました.
SPI方式で、より自然にこの問題を解決することができます.
SPIはService Provider Interfacesの略です.
本文は簡単にどのように使うかを紹介して、具体的な原理、しばらく深く研究しません.
SPIって何?
SPIはJavaが提供するサービスロード方式で、サービスプロバイダインターフェースというフルネームです.
JavaのSPI仕様に従って、対応するインプリメンテーションによって提供されるサービスインタフェース、すなわちサービスプロバイダを定義することができます.
そして使用時にSPIの仕様に従って対応するサービスプロバイダのサービス実装を取得する.
SPIサービスローディングメカニズムによるサービスの登録と発見は,コードに特定のサービスプロバイダを書き込むことを効果的に回避できる.これにより、インタフェースに基づいてプログラミングを行い、モジュール間のデカップリングを実現することができる.
SPIメカニズムの約束 META-INF/services/ディレクトリに、APIの特定のインプリメンテーションクラスのフルリミット名 であるインタフェースフルリミット名で命名されたファイルを作成する. ServiceLoaderクラスを使用してMETA-INFのインプリメンテーションクラス を動的にロード SPIの実装クラスがJarである場合、メインプログラムClassPathに を配置する必要がある. APIの特定の実装クラスには、パラメータを持たない構築方法 が必要である.
シーンの適用例
SPI適用シーンの例 JDBC
jdbc 4.0以前は、開発者はClass.forName(「xxx」)に基づいてドライバをロードする必要があり、jdbc 4もspiのメカニズムに基づいてドライバプロバイダを発見し、METAINF/services/java.sql.Driverファイルに実装クラスを指定することでドライバプロバイダを暴露することができる. COMMON-LOGGING
apacheが最初に提供したログのフェースインタフェース.インタフェースのみで、実装されていません.
具体的な案は各プロバイダによって実現され、発見ログプロバイダはMETAINF/services/org.apache.commons.logging.LogFactoryプロファイルをスキャンし、そのファイルの内容を読み取ることによってログ提工商実現類を見つける.
ログインプリメンテーションにこのファイルが含まれており、ログファクトリインタフェースのインプリメンテーションクラスをファイルに作成すればよい.
単純な実装
ファイルディレクトリ Say.java DefaultSay.java
resourcesディレクトリの下に、META-INF/servicesフォルダを作成し、インタフェースのフルパス名com.github.houb.forname.Sayをファイル名、コンテンツを対応するインプリメンテーションクラスのフルパスとします.
複数であれば、そのまま改行して区切ります. com.github.houbb.forname.Say SayTest.java 試験結果
Javaでは、ServiceLoaderクラスによって、クラスのすべてのサブクラスを容易に見つけることができます.
META-INF/servicesでのインプリメンテーション指定とインプリメンテーションサブクラスインプリメンテーションは、インタフェース定義と完全に分離できます.
面倒なところ
毎回インプリメンテーション指定ファイルを手動で作成するのは煩雑です.
Autoはこの問題を解決するために生まれた.
AutoVersionデモ
maven導入 Sing.java DefaultSing.java SingTest.java 結果
Googleのautoにより、コンパイル時に自動的に対応するインタフェースを生成して指定ファイルを実現できます.
target対応のファイルの下に表示されます.
実現原理も、比較的簡単です.Javaのコンパイル時に注記して、対応するファイルを生成すればいいです.
実際にdubboなどのフレームワークでは、SPIメカニズムを利用してプロジェクト全体の柔軟性を向上させることができます.
JAvaが持っているSPIには多くの不足点があり、本シリーズは使用を学び、自分の強化したSPIフレームワークを実現することです.
ソースアドレス
SPIソース
参考資料
Oracle SPI-intro
google auto
JAVA SPIのメカニズムと使用方法を詳しく理解する
spi 01-spiとは何ですか?使用開始
spi 02-spiの実戦解決slf 4 jパケット衝突問題
spi 03-spi jdkソースコード解析を実現
spi 04-spi dubboソースコード解析を実現
spi 05-dubbo adaptive extension適応拡張
spi 06-自分でゼロから手書きでSPIフレームワークを実現
spi 07-自動生成SPIプロファイル実装方式
問題の導入
以前は、この基準に従って実現させるための基準を指定し、対応する容器を作成したいと思っていました.
その後、コードでこれらの実装を動的に取得し、コードを実行します.
困難
インタフェースの実装をどのように取得しますか?
初歩案
同僚と議論するのは、パッケージのclassをスキャンする方法です.次に、カスタム基準のサブクラスであるかどうかを判断します.
SPIの解決方法
今日はhibernate-validatorソースコードを読んで啓発されました.
SPI方式で、より自然にこの問題を解決することができます.
SPIはService Provider Interfacesの略です.
本文は簡単にどのように使うかを紹介して、具体的な原理、しばらく深く研究しません.
SPIって何?
SPIはJavaが提供するサービスロード方式で、サービスプロバイダインターフェースというフルネームです.
JavaのSPI仕様に従って、対応するインプリメンテーションによって提供されるサービスインタフェース、すなわちサービスプロバイダを定義することができます.
そして使用時にSPIの仕様に従って対応するサービスプロバイダのサービス実装を取得する.
SPIサービスローディングメカニズムによるサービスの登録と発見は,コードに特定のサービスプロバイダを書き込むことを効果的に回避できる.これにより、インタフェースに基づいてプログラミングを行い、モジュール間のデカップリングを実現することができる.
SPIメカニズムの約束
シーンの適用例
SPI適用シーンの例
jdbc 4.0以前は、開発者はClass.forName(「xxx」)に基づいてドライバをロードする必要があり、jdbc 4もspiのメカニズムに基づいてドライバプロバイダを発見し、METAINF/services/java.sql.Driverファイルに実装クラスを指定することでドライバプロバイダを暴露することができる.
apacheが最初に提供したログのフェースインタフェース.インタフェースのみで、実装されていません.
具体的な案は各プロバイダによって実現され、発見ログプロバイダはMETAINF/services/org.apache.commons.logging.LogFactoryプロファイルをスキャンし、そのファイルの内容を読み取ることによってログ提工商実現類を見つける.
ログインプリメンテーションにこのファイルが含まれており、ログファクトリインタフェースのインプリメンテーションクラスをファイルに作成すればよい.
単純な実装
ファイルディレクトリ
.
├── java
│ └── com
│ └── github
│ └── houbb
│ └── forname
│ ├── Say.java
│ ├── Sing.java
│ └── impl
│ ├── DefaultSay.java
│ └── DefaultSing.java
└── resources
└── META-INF
└── services
└── com.github.houbb.forname.Say
インタフェースと実装の定義public interface Say {
/**
*
*/
void say();
}
import com.github.houbb.forname.Say;
public class DefaultSay implements Say {
@Override
public void say() {
System.out.println("Default say");
}
}
サービス実装指定の作成resourcesディレクトリの下に、META-INF/servicesフォルダを作成し、インタフェースのフルパス名com.github.houb.forname.Sayをファイル名、コンテンツを対応するインプリメンテーションクラスのフルパスとします.
複数であれば、そのまま改行して区切ります.
com.github.houbb.forname.impl.DefaultSay
テストpublic class SayTest {
@Test
public void spiTest() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ServiceLoader loader = ServiceLoader.load(Say.class, classLoader);
for (Say say : loader) {
say.say();
}
}
}
Default say
簡単にまとめるJavaでは、ServiceLoaderクラスによって、クラスのすべてのサブクラスを容易に見つけることができます.
META-INF/servicesでのインプリメンテーション指定とインプリメンテーションサブクラスインプリメンテーションは、インタフェース定義と完全に分離できます.
面倒なところ
毎回インプリメンテーション指定ファイルを手動で作成するのは煩雑です.
Autoはこの問題を解決するために生まれた.
AutoVersionデモ
maven導入
com.google.auto.service
auto-service
1.0-rc4
true
インタフェースと定義public interface Sing {
/**
*
*/
void sing();
}
@AutoService(Sing.class)
public class DefaultSing implements Sing {
@Override
public void sing() {
System.out.println("Sing a song...");
}
}
テストpublic class SingTest {
@Test
public void spiTest() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
ServiceLoader loader = ServiceLoader.load(Sing.class, classLoader);
for (Sing sing : loader) {
sing.sing();
}
}
}
Sing a song...
簡単にまとめるGoogleのautoにより、コンパイル時に自動的に対応するインタフェースを生成して指定ファイルを実現できます.
target対応のファイルの下に表示されます.
実現原理も、比較的簡単です.Javaのコンパイル時に注記して、対応するファイルを生成すればいいです.
実際にdubboなどのフレームワークでは、SPIメカニズムを利用してプロジェクト全体の柔軟性を向上させることができます.
JAvaが持っているSPIには多くの不足点があり、本シリーズは使用を学び、自分の強化したSPIフレームワークを実現することです.
ソースアドレス
SPIソース
参考資料
Oracle SPI-intro
google auto
JAVA SPIのメカニズムと使用方法を詳しく理解する