動的プロキシが通常のプロキシよりも役立つシナリオについてアドバイスが必要です。
私は、動的プロキシを効果的に使用する方法を学ぶことに多大な努力を払ってきました。この質問では、AspectJ のようなフレームワークが基本的に動的プロキシで達成しようとするすべてのことを実行できること、または動的プロキシのいくつかの欠点に対処するために CGLIB を使用できることは脇に置いておいてください。
ユースケース
- デコレータ - たとえば、メソッド呼び出しのロギングを実行したり、複雑な操作の戻り値をキャッシュしたりします
- 契約を維持する - つまり、パラメーターが許容範囲内にあり、戻り値の型が許容値に準拠していることを確認します。
- アダプター - これがどのように役立つかを説明する巧妙な記事をどこかで見ました。ただし、このデザインパターンに出くわすことはめったにありません。
他は?
動的プロキシの利点
- デコレーター: すべてのメソッド呼び出しをログに記録します。
public Object invoke(Object target, Method method, Object[] arguments) {
System.out.println("before method " + method.getName());
return method.invoke(obj, args);
}
}
デコレータ パターンは、すべてのプロキシ メソッドに副作用を与えることができるため、間違いなく便利です (ただし、この動作はアスペクトを使用する本の例です)。
- コントラクト: 通常のプロキシとは対照的に、完全なインターフェイスを実装する必要はありません。例えば、
public Object invoke(Object target, Method method, Object[] arguments) {
if ("getValues".equals(method.getName()) {
// check or transform parameters and/or return types, e.g.,
return RangeUtils.validateResponse( method.invoke(obj, args) );
}
if ("getVersion".equals(method.getName()) {
// another example with no delegation
return 3;
}
}
一方、コントラクトには、完全なインターフェイスを実装する必要がなくなるという利点しかありません。繰り返しますが、プロキシされたメソッドをリファクタリングすると、動的プロキシが暗黙のうちに無効になります。
結論
ここで私が目にするのは、実際の使用例と疑わしい使用例の 1 つです。あなたの意見は何ですか?