きどたかのブログ

いつか誰かがこのブログからトラブルを解決しますように。

いまさらJavaSE6のServiceLoaderを触ってみた

DIコンテナ主流の時代で使われることのないServiceLoader。
CDIでてきてから一層使われることのないServiceLoader。
Javaのごく一部で使われているServiceLoader。
一般的なプログラマが基本的に使う必要性がないServiceLoader。


「サービスを表すインタフェースもしくは抽象クラス」と「サービスを実現する実装クラス」のマッピングをするための機構。
細かいインジェクションの類はできない。
サービス実装クラスの下準備の処理がコンストラクタに集中するか、
他の何かにしわ寄せがくるんだろうな。


サービスは決して1対1のマッピングではない。
META-INF/servicesフォルダに置くサービス構成ファイルに複数行で実装クラスを書けばいい。
少なくとも自分でそう書いたものは複数のサービスを取得できた。
いちおう複数Jar(複数Jarに、中身の異なる同名のサービス構成ファイルがあるパターン)でも動く。


使いどころが難しいreload()メソッド
新しいサービスが追加されたときに再読み込みをするために使うメソッドだけれど、
新しいサービスが追加されたことを検知する仕組みはない。
JavaSE7のWatchServiceとでも組み合わせるべきなんだろうか?
もちろんそれだけではダメだろう、きっとClassLoaderも自前のものを用意しないといけない気がする。
ClassLoaderなんて作りたくない。やだやだ。


Run As Java Applicationで手軽に動かせない。
ServiceLoaderの実装は変更できない。
必ずMETA-INF/services/を探す。
つまり、Jarになっていない状態ではサービス構成ファイルを見つけられない。
当たり前だ、クラスパスに通ってないリソースが見えてたまるか。
srcフォルダの下に「META-INF/services/サービス構成ファイル」を作れば動く。
でも、そんなの嫌だ、許せるわけがなかろうもん。
せめてMaven構成でresourcesフォルダにMETA-INF/servicesを作ってクラスパス通す感じだろうな。


自分でプロパティファイル作って、それをサービス構成ファイルに読み替えてコード書いた方が柔軟だろうよ。