5

誰もがJavaServiceProviderで不快なブラシを持っているようです。これは、 META-INF / services / com.example.Interfaceのような名前のファイルで実行できますが、適切なXMLパーサーをロードする以外は誰も使用しません。 。Service Provider APIを使用するライブラリを操作しようとしていますが、実際にはインターフェイスを実装していないが、簡単に実装できるランタイム拡張クラス(cglibを使用)を提供できるようにトリックしています。

基本的に、実行する必要のある手順は次のとおりです。

  1. getResources(...)に応答し、「追加の」URLを返すカスタムクラスローダーを作成します
  2. また、そのクラスローダーフックgetResourceAsStream(...)を使用して、「追加の」リソースを要求されたときに、cglibで操作するクラスのリストを返します。
  3. 最後に、要求されたときにそのクラスローダーにそれらのクラスをロードさせます

しかし、ここで私は迷子になります。たとえば、ライブラリがそこにある実装者を判別しようとすると、getResources(...)を呼び出して、一連のURLを返します。ただし、getResourceAsStream(...)はURLを使用せず、「名前」を使用します。クラスパスに関連しているように見える名前。したがって、どこでも同じです。つまり、META-INF / services / com.example.Interfaceは、JARのMETA-INF / services / com.example.Interfaceと同じ「名前」を持っていますよね?どういうわけかこれがそれらの爆破されたXMLパーサーで機能することを除いて...

もちろん、これはすべて、ClassLoader.getSystemResources(...)、ClassLoader.getSystemResourceAsStream(...)などを使用するのではなく、ClassLoader.getSystemClassLoader()を呼び出すのに十分賢い/親切であることを前提としています。 ClassLoaderをフックして、偽のファイルを提供する方法はありません。

その場合、cglibで実行するまで待つのではなく、コードがMavenによってパッケージ化されているときに、BCELを使用してクラスファイルを操作できると思いますか?

4

1 に答える 1

3

私が説明したアイデアは正しい方向に進んでいました。私が犯した間違いClassLoader.getResourceAsStream(..)は、URLのコンテンツにアクセスするために使用することを考えていたことです。代わりに、あなたはただURL.openStream()

投稿する前にそれを見つけていたらjava.util.ServiceLoader(@1.6以降)、物事を正しく行う方法についての洞察が得られます。

于 2010-12-27T11:25:58.957 に答える