私は、動的にJavaインターフェイスメソッドの実装を生成すること、および既存のプロキシオブジェクトの単一方法にこれらのメソッドへの呼び出しを委任するバイトバディを使用しています。
最初のバージョンは、触発されたByteBuddyを使用して動的プロキシを作成する方法
これは、リフレクションを使用しています InvocationHandler
すなわち、具体的なプロキシクラスは:
- インターフェイスを実装
InvocationHandler
- オーバーライドメソッド
invoke()
これは、罰金に動作します。
その後、再読み込みのGithub上のバイトバディのreadme私が使用して代替バージョンを発見しMethodDelegation
、「GeneralInterceptor」にします。
すなわち、具体的なプロキシクラスは:
- でマークされた方法がある
RuntimeType
注釈を。
また、これは罰金を作品!
以下のコードスニペットは、両方の技術を示しています。
Class<? extends Object> clazz = new ByteBuddy()
.subclass(serviceSuperClass)
.name(className)
// use a Reflection InvocationHander for the methods of serviceInterfaceOne
.implement(serviceInterfaceOne)
.defineField(invocationHandler, MyProxy.class, Visibility.PUBLIC)
.method(isDeclaredBy(serviceInterfaceOne))
.intercept(InvocationHandlerAdapter.toField(invocationHandler))
// use a Byte-Buddy "GeneralInterceptor" for the methods of serviceInterfaceTwo
.implement(serviceInterfaceTwo)
.defineField(generalInterceptor, MyProxy.class, Visibility.PUBLIC)
.method(isDeclaredBy(serviceInterfaceTwo))
.intercept(MethodDelegation.toField(generalInterceptor))
//
.make ()
.load(classLoader)
.getLoaded();
public class MyProxy implements InvocationHandler {
@Override
public Object invoke(Object serviceImpl, Method method, Object[] args) throws Throwable {
return null;
}
@RuntimeType
public Object intercept(@AllArguments Object[] allArguments,
@Origin Method method) {
return null;
}
}
高レベルのポイント・オブ・ビューの両方の手法から、私は同じことを行うことができ:
すなわち、既存の具体的な方法に与えられた動的に作成する方法をインターセプト。
両方の溶液はエレガントであり、必要なコードの量が類似しています。
質問は次のとおりです。他の上の1つを好むために何らかの理由があるのでしょうか?例えばパフォーマンス?機能性?
使用のこの形態では、呼び出しハンドラアダプタのみJavaのプロキシAPIの実装をブリッジに対し任意の(静的または非静的)メソッドに配線することができる委任以外に実質的な違いは存在しません。あなたはすでに、このようなプロキシハンドラを実装し、バイトバディでそれらを再利用したい場合には、主に意味します。
バイトバディのハンドラを使用すると、引数が期待するものを知っている場合は、例えば、配列ボクシングを避けることができるので、パフォーマンスを向上させ、その後、ハンドラのAPIより柔軟になります。また、呼び出しハンドラのAPIがサポートされていないことをデフォルトのメソッドの実装を呼び出すような異なるメカニズムが可能になります。