この記事では、主に Java の静的プロキシ、動的プロキシ、および CGLIB 動的プロキシの概要を紹介します。興味のある方は学習してください。プロキシ パターンは、Java で最もよく使用されるデザイン パターンの 1 つです。特に Spring フレームワークで広く使用されています。 Java のプロキシ モードは、一般に、静的プロキシ、動的プロキシ、および CGLIB 動的プロキシに分類できます。
上記の 3 つのプロキシ モードについては個別に説明します。
静的プロキシとは、実際にはプログラムを実行する前に事前にプロキシメソッドのプロキシクラスを記述しておき、コンパイル後に実行するものです。クラスはプログラムが実行される前にすでに存在しています。
以下では、静的プロキシのデモを実装します。静的プロキシ
インターフェイス Target
package com.test.proxy; public interface Target { public String execute(); }
package com.test.proxy; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }
rreee
テストクラス:
package com.test.proxy; public class Proxy implements Target{ private Target target; public Proxy(Target target) { this.target = target; } @Override public String execute() { System.out.println("perProcess"); String result = this.target.execute(); System.out.println("postProcess"); return result; } }
package com.test.proxy; public class ProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); Proxy p = new Proxy(target); String result = p.execute(); System.out.println(result); } }
動的プロキシは主にリフレクションメカニズムを使用して、実行時に必要なプロキシのクラスを動的に生成します。
動的プロキシ
Interface
perProcess TargetImpl execute! postProcess execute
package com.test.dynamic; public interface Target { public String execute(); }
package com.test.dynamic; public class TargetImpl implements Target { @Override public String execute() { System.out.println("TargetImpl execute!"); return "execute"; } }
package com.test.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyHandler implements InvocationHandler{ private Target target; public DynamicProxyHandler(Target target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("========before=========="); Object result = method.invoke(target,args); System.out.println("========after==========="); return result; } }
package com.test.dynamic; import java.lang.reflect.Proxy; public class DynamicProxyTest { public static void main(String[] args) { Target target = new TargetImpl(); DynamicProxyHandler handler = new DynamicProxyHandler(target); Target proxySubject = (Target) Proxy.newProxyInstance(TargetImpl.class.getClassLoader(),TargetImpl.class.getInterfaces(),handler); String result = proxySubject.execute(); System.out.println(result); } }
CGLib は、非常に低レベルのバイトコード テクノロジを使用します。原理は、バイトコード テクノロジを通じてクラスのサブクラスを作成し、サブクラス内のメソッド インターセプト テクノロジを使用してすべての親クラスのメソッド呼び出しをインターセプトすることです。横断的なロジックが織り込まれています。 JDK 動的プロキシと CGLib 動的プロキシは両方とも、Spring AOP を実装するための基礎です。
cglib動的プロキシ
ターゲットクラス
========before========== TargetImpl execute! ========after=========== execute
package com.test.cglib; public class Target { public String execute() { String message = "-----------test------------"; System.out.println(message); return message; } }
package com.test.cglib; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class MyMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println(">>>>MethodInterceptor start..."); Object result = proxy.invokeSuper(obj,args); System.out.println(">>>>MethodInterceptor ending..."); return "result"; } }
package com.test.cglib; import net.sf.cglib.proxy.Enhancer; public class CglibTest { public static void main(String ... args) { System.out.println("***************"); Target target = new Target(); CglibTest test = new CglibTest(); Target proxyTarget = (Target) test.createProxy(Target.class); String res = proxyTarget.execute(); System.out.println(res); } public Object createProxy(Class targetClass) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(targetClass); enhancer.setCallback(new MyMethodInterceptor()); return enhancer.create(); } }
1. エージェント クラス Class のバイナリ バイトコードを生成します。
2. Class.forName を通じてバイナリ バイトコードをロードして、Class オブジェクトを生成します。 ;
3. リフレクション機構がインスタンス構築を取得し、プロキシ クラス オブジェクトを初期化します。
以上がJava の静的プロキシ、動的プロキシ、および CGLIB 動的プロキシの詳細な説明 (図)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。