JerseyのServiceクラス探索がどうなっているのか調べてみた
JAX-RSの実装であるJaersyでは、アノテーションを付与したサービスクラスを自動で探索して、デプロイしてくれます。マッピングを指定するわけでもなく、もちろん「META-INF/services/...」とかも不要。んー、内部実装はどうなってるんだろー、気になるー!、ということで調べてみた。
結果
以下のような仕組みでした。
- 「java.util.jar.JarFile」を使ってクラスパスに含まれるjarを展開。
- エントリを列挙して「.class」で終了するファイルを探索し、
- マッチしたエントリをASMで解析。
- クラスに指定されたアノテーションがついていれば、サービスと見なして一覧に追加。
探索のメインクラスはjersey-server-1.1.1-ea.jarに含まれる「com.sun.jersey.server.impl.container.config.AnnotatedClassScanner」になります。ソースはMavenリポジトリの「jersey-server-1.1.2-ea-SNAPSHOT-sources.jar」の中にあります。
んー、これだとクラスパス上にjarが大量にある場合、探索に時間がかかるんでは・・・・。とはいえ、「META-INF/services/...」などがいらないのはメリットなので、マッピングを明示的に指定しない場合に使える探索方式の一つとして提供されている、とかなら活用できそう。あと、クラスの解析にASM使ってるのはポイントかも。バイトコードを直接読んでるので、探索してもクラス自体はロードされないはず。ふむふむ。