1.静的プロキシ
静态代理
プロキシクラスとプロキシクラスは、同じインターフェイスを実装するか、同じ親クラスを継承する必要があります。具体的な考え方は、プロキシクラスにターゲットインターフェイス属性を設定し、ターゲットインターフェイスをパラメータとして構築メソッドを提供し、同時にターゲットインターフェイスを実現することです。次に、プロキシオブジェクトをポリモーフィズムの形式で渡して、プロキシオブジェクトの作成を完了します。
优点:
実際のオブジェクトのビジネスロジックの外部への露出を回避しながら、ターゲットオブジェクトの機能を変更せずにターゲット機能を拡張することが可能です。
缺点:
インターフェイスを実装する必要があるため、コードは煩雑で保守が困難です。
2.動的プロキシ
ダイナミック薬の主に2つのタイプがありますJDK动态代理(接口代理)
し、Cglib动态代理(子类代理)
1.JDK動的プロキシ
JDK动态代理
プロキシクラスは必ずしもターゲットインターフェイスを実装する必要はありませんが、ターゲットクラスはターゲットインターフェイスを実装する必要があります。具体的なアイデアは次のとおり
です。a。Javaリフレクションロードターゲットインターフェイスを介してクラスオブジェクトを取得します。
b。ハンドラーハンドル(InvocationHandlerインターフェイス)を介してコンストラクターを取得します。
c。次に、ターゲットオブジェクトをポリモーフィズムの形式でハンドラーハンドルに挿入します。
d。プロキシハンドラハンドルに基づいてプロキシクラスオブジェクトインスタンスを構築し、ターゲットインターフェイスへのプロキシの完了を強制します。
@Test
public void t() throws Exception{
Subject realSubject = new RealSubject();
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
//1.0 获取代理类的类对象,主要设置相同的ClassLoader去加载目标类实现的接口Subject类
Class<?> proxyClass = Proxy.getProxyClass(Client.class.getClassLoader(), new Class[]{
Subject.class});
//2.0 得到代理类后,就可以通过代理类的处理器句柄来得到构造器
final Constructor<?> con = proxyClass.getConstructor(InvocationHandler.class);
//3.0 获取具体执行方法的句柄处理器,目的通过构造器传入被代理目标类对象,注入到代理类处理器句柄中进行代理调用
final InvocationHandler handler = new DynamicProxy(realSubject);
//4.0 通过构造器创建代理类对象
Subject subject = (Subject)con.newInstance(handler);
//5.0 最后调用方法
subject.hello("proxy");
注:ここで、DynamicProxyクラスはInvocationHandlerインターフェースを実装し、invokeメソッドをオーバーライドします。
さらに、JDK動的プロキシがインターフェースのプロキシのみを実装できる理由はJavaのためです单继承机制
。プロキシクラスはjava.lang.reflect.Proxyクラスを継承し、渡したインターフェイスを実装しました。Javaは複数の継承クラスを許可しませんが、複数の実装インターフェイスを許可するため、関数の拡張はターゲットインターフェイスを実装することによってのみ実現できます。
优点:
静的プロキシでの冗長プロキシ実装の問題を解決します。
缺点:
インターフェイスを実装していないクラスをプロキシすることはできません。
参照リンク:JDK動的プロキシ主成分分析
2.Cglib動的プロキシ
Cglib动态代理
基盤となるバイトコード拡張テクノロジーを通じて、オブジェクトのプロキシを実現します。具体的なアイデアは、プロキシクラスを継承してプロキシサブクラスを作成し、MethodInterceptorインターフェイスを実装し、すべての親クラスのメソッド呼び出しをインターセプトし、インターセプトメソッドをオーバーライドしてから、Enhancerクラスのコールバックメソッドを介して動的プロキシを完成させることです。
优点:
インターフェイスを実装しないクラスを動的にプロキシすることもできます。
缺点:
テクノロジーはもっと複雑です...
注:Cglib動的プロキシはサブクラスオブジェクトを作成することによって実装されるため、Cglibはfinalキーワードによって変更されたメソッドを処理できません。