リフレクション無しにjar間のクラスを解決する作りこみ
slf4j,logbackの仕組みから学んだ方法
※既存のシステムに対して行うというより、これから作るjarモジュールの
分割する方法として使える方法ですな。
api.jarとimpl.jarがあり、クライアントはimpl.jarの実装を直接触れずに
api.jarだけ利用するような。インタフェースと実装を切り分ける構成の場合。
impl.jarのクラスの解決はClass.forName()などのリフレクションで行う。
この場合、ロードするクラス名を設定ファイル等でどこかに保持しておく
必要がある。
slf4jの仕組みでは、リフレクションを使わず、クラスパスでのクラス定義
解決を利用する。
1.api.jarはコンパイル時、スタブimplクラスをつくってコンパイルする。
2.jar作成時、スタブimplクラスファイルを抜き不完全なjarを作成する。
3.impl.jarにapi.jarで間引いた、implクラスを実装する。
これがimpl.jarのfacadeクラスに当たる。
4.クラスパス解決時にapi.jarだけでは不完全のため、他のjar(ここでは
impl.jar)の同名クラスで解決する。
これにより、実装とインタフェースを分けたモジュールを何の機構も
無しに解決することができる。
なんだかC/C++のリンクに似てる感じ。
後はimpl.jarがない場合のClassNotFoundException()だけ処理して
アプリ自体が死なないようにすれば良いわけか。
javaだからこそビルド後"ファイルを間引く"という技が使えるわけで。
これはいいアイデアだ。
pluginのような動的な差し替えが起こらなければ、十分なわけで。
凝った機構を作りこむわけでもなく非常にシンプル。
よく知られた手法なのかな?
些細なことなんだろうけど、私には到底思いつかないアイデアだなあ。
※既存のシステムに対して行うというより、これから作るjarモジュールの
分割する方法として使える方法ですな。
api.jarとimpl.jarがあり、クライアントはimpl.jarの実装を直接触れずに
api.jarだけ利用するような。インタフェースと実装を切り分ける構成の場合。
impl.jarのクラスの解決はClass.forName()などのリフレクションで行う。
この場合、ロードするクラス名を設定ファイル等でどこかに保持しておく
必要がある。
slf4jの仕組みでは、リフレクションを使わず、クラスパスでのクラス定義
解決を利用する。
1.api.jarはコンパイル時、スタブimplクラスをつくってコンパイルする。
2.jar作成時、スタブimplクラスファイルを抜き不完全なjarを作成する。
3.impl.jarにapi.jarで間引いた、implクラスを実装する。
これがimpl.jarのfacadeクラスに当たる。
4.クラスパス解決時にapi.jarだけでは不完全のため、他のjar(ここでは
impl.jar)の同名クラスで解決する。
これにより、実装とインタフェースを分けたモジュールを何の機構も
無しに解決することができる。
なんだかC/C++のリンクに似てる感じ。
後はimpl.jarがない場合のClassNotFoundException()だけ処理して
アプリ自体が死なないようにすれば良いわけか。
javaだからこそビルド後"ファイルを間引く"という技が使えるわけで。
これはいいアイデアだ。
pluginのような動的な差し替えが起こらなければ、十分なわけで。
凝った機構を作りこむわけでもなく非常にシンプル。
よく知られた手法なのかな?
些細なことなんだろうけど、私には到底思いつかないアイデアだなあ。
コメント