2012-04-20 9 views
2

私は今、韓国語で書かれた春の本を読んでいて、私の英語は悪いです。それを理解してください。spring aop proxyオブジェクト

本書では、SpringのAOPは、Interfaceを使用する場合はDynamicプロキシを使用してクラスを開始し、Interfaceを使用しない場合はCGLIBを使用してクラスを開始します。 私はそれが何を意味するかをはっきりと理解していません。その深い意味を理解するのを助けてくれますか?

私はこの質問が愚かであるかどうかわかりません。私はちょうど興味があるTHXです。

答えて

8

プロキシは本質的に、クライアントとオブジェクトの間の仲介者であり、オブジェクトの非最終的なメソッドを実装します。インターフェイスは、実装が必要なメソッドのリストにすぎず、メソッド呼び出しの代行受信を容易にするため、インターフェイスのプロキシ処理は比較的簡単です。

JavaのProxyクラスは、実行時に指定されたインタフェースのリストを実装するクラスです。プロキシにはInvocationHandlerが関連付けられており、プロキシに対して行われたメソッド呼び出しを代理対象のオブジェクトに委任します。これは、メソッドがオブジェクト自体ではなくそのプロキシで呼び出されるように、間接指示のレベルとして機能します。 InvocationHandlerを実装する必要がある単一の方法があるが、:

public Object invoke(Object proxy, Method method, Object[] args) 

を一方、メソッドを呼び出すクライアントは、プロキシおよびその基礎となるオブジェクト表現の違いを見分けることができない、またそれは気にする必要があります。

インターフェイスとは対照的に、クラスを動的にプロキシすることはあまり簡単ではありません。 JavaのProxyはインターフェイスまたはインターフェイスセットの実行時実装に過ぎませんが、オブジェクトはにはインターフェイスを実装するためにがありません。したがって、プロキシクラスでは、cglibなどのライブラリが動作するバイトコード生成が必要です。 cglibは、JavaのProxyが実行時にインタフェースを実装できるように、実行時にクラスを拡張できるという意味で、バイトコード(つまりクラスファイル)を動的に生成できるため、プロキシクラスをサポートしています。

多くのプロキシが使用されています。そのような使用の1つは遅延ロードです。レイジーローディングは、オブジェクトグラフ内のオブジェクトが必要なときにのみ読み込まれるようにします。高価でリソースを大量に消費する可能性のある、すべてをすぐにメモリにロードするのではなく、オブジェクトのコレクションを繰り返し処理するなど、アクセスする必要が生じたときにオンザフライで読み込むことができます。コレクション全体を読み込むのではなく、一度に小さなセットを読み込むだけです。これは、プロキシで実現できます。プロキシは遅延ロードされたオブジェクトを表します。データベースからロードされる可能性のあるオブジェクト自体は、プロキシでメソッドが呼び出されるまでロードされません。メソッド呼び出しをインターセプトするプロキシは、オブジェクトをメモリにロードし、メソッド呼び出しをそのメソッドに委譲します。ここ

は、レイジーローディングの実装の例である:

public abstract class LazilyLoadedObject implements InvocationHandler { 

    private Object target; 

    @Override 
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 
     if (target == null) { 
      target = loadObject(); 
     } 
     return method.invoke(target, args); 
    } 

    /** 
    * Loads the proxied object. This might be an expensive operation 
    * or loading lots of objects could consume a lot of memory, so 
    * we only load the object when it's needed. 
    */ 
    protected abstract Object loadObject(); 

} 

プロキシで呼び出されたメソッドがInvocationHandlerによって処理されるように上記InvocationHandlerプロキシに渡すことになります。ハンドラは、オブジェクトがロードされているかどうかをチェックします。それがなければ、loadObject()が呼び出されます。これはオブジェクトを取得する何らかのデータベースクエリです。

プロキシはメソッド呼び出しの代行受信を可能にするので非常に強力です。これはAOPの場合です。

+0

私はこの部分(return method.invoke(target、args);)が無限ループになると思います。 –

+1

いいえ、 'InvocationHandler'が' target'のメソッドを呼び出すため、プロキシではなく実際のオブジェクトです。代わりに 'return method.invoke(proxy、args) 'を呼び出すと、無限ループになります。 –

+0

aha。あなたが正しい –

2

Java Dynamic Proxyは、実行時にユーザーがインターフェイスのプロキシを作成できるようにするJava言語の反射要素です。リフレクションパッケージの一部として、それはJavaの一部であり、JRE/JDKとともに出荷されます。

CGLIBは、実行時にJavaクラスを拡張する機能を持つコード生成ライブラリです。このため、Springはこの機能を利用して、AOPライブラリ用の非インタフェースをプロキシします。

関連する問題