最近、プロキシオブジェクトを扱っていると、難しい質問にたどり着きました...それを共有し、あなたの意見を聞きたいです...おそらく、解決策...質問が有効であることが証明された場合。
動的プロキシを使用して、作業をclass
を実装する別のものに委譲しInvocationHandler
interface
、invoke メソッドを上書きすることで、ターゲット オブジェクトで呼び出された任意のメソッドをインターセプトできます。これにより、動作を追加し、後でターゲット オブジェクトに委譲する可能性が与えられます (おそらく実または他のプロキシ) リフレクションを使用します。プロキシしたいオブジェクトを持つ a が実装されている必要がありますinterface
。concrete
class
そのため、インターフェイスを操作します。
問題は、プロキシオブジェクトでは最初に呼び出されたメソッドのみがインターセプトされるためだと思います...つまり、concrete
オブジェクトのメソッド内(インターフェースではなくクラスが具象であるオブジェクト)の場合、他のインスタンスメソッドへの呼び出しがあります、これらのメソッドはconcrete
、プロキシ経由ではなく、オブジェクトによって直接呼び出されます(呼び出しハンドラーを再度考えて渡す前に)。interface
「動的プロキシ」のクラスは のサブクラスと見なされますが、クラスのサブクラスとは見なされないことを知っていconcrete
ます..クラス内ではconcrete
、プロキシオブジェクトクラスがサブタイプでない限り、「this」キーワードはプロキシオブジェクトを参照できませんof concrete
..、実際には「動的プロキシ」のクラスのconcrete
ための「兄弟」ですconcrete
interface
.
見てください。次のシナリオをコードに入れてください。かなり問題のある状況が見つかりました。
public class Example
{
static interface OutputerInterface
{
String getText();
void out();
void setText(String data);
}
static class Outputer implements OutputerInterface {
private String txt;
public Outputer()
{
this.txt = null;
}
@Override
public String getText()
{
return txt;
}
@Override
public void setText(String data)
{
this.txt = data;
}
@Override
public void out () {
String text = this.getText();
System.out.println (text);
}
}
static class OutputerInvocationHandler implements InvocationHandler {
private OutputerInterface outputer;
public OutputerInvocationHandler(OutputerInterface concreteEntity)
{
this.outputer = concreteEntity;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
String methodName = method.getName();
System.out.println("Intercepted " + methodName);
if (methodName.equals("getText"))
{
if (this.outputer.getText() == null) { // only if not setted
this.outputer.setText("Hi, i am outputer");
}
}
return method.invoke(outputer, args);
}
}
static OutputerInterface proxify (OutputerInterface entity) {
return (OutputerInterface) Proxy.newProxyInstance(
Outputer.class.getClassLoader(),
Outputer.class.getInterfaces(),
new OutputerInvocationHandler(entity));
}
public static void main(String[] args)
{
OutputerInterface outputer;
outputer = proxify (new Outputer());
String text = outputer.getText();
System.out.println (text); // this works!
outputer = proxify (new Outputer());
outputer.out(); // this doesn´t works
}
}
getText() がプロキシから直接呼び出されたかどうかにかかわらず、確実に傍受されるようにする方法はありますか。ありがとう!ご挨拶!ビクター。