2016-04-23 1 views
2

私はJavaがプロキシをサポートしていることを知っています。私はJavassistをチェックしていますが、次のトリックをサポートできるかどうかはわかりません:Java:実行時にライブオブジェクトインスタンスにプロキシを追加/接続することは可能ですか?

public class Hello { 

    public void hi() { 
     System.out.println("hi"); 
    } 
} 

Hello hello = new Hello(); 

Hello proxyHello = createProxy(hello); 
proxyHello.hi(); // method will be intercepted by a predefined proxy 

このようなことは可能ですか?

答えて

1

プロキシを作成するクラスからアクセス可能なコンストラクタが必要です。ここで

はあなたが必要なものを実装する方法です:

final Hello hello = new Hello() { 
    public void hi() { 
     System.out.println("Hello World"); 
    } 
}; 
ProxyFactory factory = new ProxyFactory(); 
factory.setSuperclass(Hello.class); 
MethodHandler handler = (self, m, proceed, args) -> { 
    // This allows to proxy even non accessible methods, it could not be 
    // needed depending on your context 
    if (!m.isAccessible()) 
     m.setAccessible(true); 
    return m.invoke(hello, args); 
}; 
Hello proxy = (Hello)factory.create(new Class<?>[0], new Object[0], handler); 
proxy.hi(); 

は出力:この例では

Hello World 

  1. まず、私は私の工場
  2. を作成します
  3. その後、私はその後、私は
  4. 最後に、私はここで私はデフォルトを使用(私のプロキシを作成(ここで私は私のライブオブジェクトにすべてを委任する)メソッドは、プロキシに呼び出すすべてを処理する方法を定義し
  5. スーパークラスを提供プロキシを作成するコンストラクタ)。

    ここ
    Hello proxy = (Hello)factory.create(
        new Class<?>[]{String.class}, new Object[]{"bar"}, handler 
    ); 
    

    私は1つの引数を持つコンストラクタを呼び出す:あなたは次のように最後の行を変更する必要があります1つのString引数を持つコンストラクタを持っていると仮定すると

詳細here

タイプStringであり、値としてbarを提供しました。

+0

ニースのニコラス!しかし、これは既定のコンストラクタの単純なケース、つまり、私のクラスがゼロ引数のコンストラクタだけを取る場合にのみ機能します。別のコンストラクタを使ってオブジェクトを作成した場合は、問題が発生します。 –

+0

いいえあなたは工場の作成メソッドの引数を変更するだけです –

+0

@PikaSucar具体的な例を与えるために私の答えを更新しました –

0

java.lang.reflect.Proxyを使用すると、このような処理を行うことができます。 JDKで提供されていますが、唯一のあなたがClassのプロキシを作成したい場合は、あなたがJavassistを使用する必要がありますが、行うことができるように、インターフェイスのセットを実装するプロキシを作成することができますどのような

https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Proxy.html

+0

いいえ、私の友人はいません –

+0

'' Hello''にインターフェースを実装させることができますか?あなたが正しくなければ、 '' Proxy''はあなたのために働きません。 – ck1

関連する問題