私は今韓国語で書かれた春の本を読んでいます、そして私の英語は悪いです。理解してください。
この本では、SpringのAOPは、インターフェイスを使用する場合は動的プロキシを使用してクラスを開始し、インターフェイスを使用しない場合はCGLIBを使用してクラスを開始すると述べています。それが何を意味するのかはっきりとはわかりません。その深い意味を理解するのを手伝ってくれませんか。
この質問がばかげているかどうかはわかりません。しかし、私はTHXに興味があります。
プロキシは基本的に、クライアントとオブジェクトの間のメディエーターであり、オブジェクトの非最終メソッドを実装します。インターフェイスは単に実装する必要のあるメソッドのリストであり、メソッド呼び出しの傍受を容易にするため、インターフェイスのプロキシは比較的簡単です。
JavaのProxyクラスは、実行時に指定されるインターフェースのリストを実装するクラスです。次に、プロキシにはInvocationHandlerが関連付けられており、プロキシで行われたメソッド呼び出しをプロキシされるオブジェクトに委任します。これは、メソッドがオブジェクト自体ではなくそのプロキシで呼び出されるように、間接参照のレベルとして機能します。InvocationHandler
実装する必要があるメソッドは1つだけです。
public Object invoke(Object proxy, Method method, Object[] args)
一方、メソッドを呼び出すクライアントは、プロキシとその基になるオブジェクト表現の違いを区別できず、気にする必要もありません。
インターフェイスとは対照的に、クラスを動的にプロキシすることは、それほど単純ではありません。JavaProxy
は、インターフェイスまたはインターフェイスのセットのランタイム実装にすぎませんが、オブジェクトはインターフェイスを実装する必要はありません。したがって、クラスのプロキシにはバイトコードの生成が必要です。バイトコードの生成では、cglibなどのライブラリが役立ちます。cglibは、バイトコード(つまりクラスファイル)を動的に生成できるため、クラスのプロキシをサポートします。つまり、JavaProxy
が実行時にインターフェイスを実装できるように、実行時にクラスを拡張できます。
プロキシには多くの用途があります。そのような用途の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の場合です。
Java Dynamic Proxyは、ユーザーが実行時にインターフェースのプロキシーを作成できるようにするJava言語の反射要素です。リフレクションパッケージの一部であるため、Javaの一部であり、JRE/JDKに付属しています。
CGLIBは、実行時にJavaクラスを拡張する機能を備えたコード生成ライブラリです。このため、Springはこの機能を利用して、AOPライブラリの非インターフェイスをプロキシします。