javaプロキシとは何ですか?
プロキシは、ターゲット オブジェクトにアクセスする別の方法、つまりプロキシ オブジェクトを介してターゲット オブジェクトにアクセスする方法を提供する設計パターンです。対象オブジェクトを変更することなく、対象オブジェクトの機能を拡張できます。
エージェントの役割: コードの冗長性を削減します。
プロキシモードの実装は静的実装と動的実装の2つに分類され、動的実装は実装方法によりjdk動的実装、cglib動的実装に分かれます
3 Java の種類 エージェント モード
上記の要件を達成するには 3 つの方法があります。このパートでは、3 つのモードのコードの記述方法のみを説明し、実装については説明しません。まず原則。
1. 静的プロキシ
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } } /** * 代理对象和目标对象实现相同的接口 */ public class SingerProxy implements ISinger{ // 接收目标对象,以便调用sing方法 private ISinger target; public UserDaoProxy(ISinger target){ this.target=target; } // 对目标对象的sing方法进行功能扩展 public void sing() { System.out.println("向观众问好"); target.sing(); System.out.println("谢谢大家"); } }
Test
/** * 测试类 */ public class Test { public static void main(String[] args) { //目标对象 ISinger target = new Singer(); //代理对象 ISinger proxy = new SingerProxy(target); //执行的是代理的方法 proxy.sing(); } }
メリット:対象オブジェクトの機能を変更せずに対象機能を拡張
デメリット:この実装方法非常に直感的でシンプルですが、プロキシ オブジェクトを事前に記述しておく必要があり、インターフェイス層が変更された場合でもプロキシ オブジェクトのコードも維持する必要があるという欠点があります。プロキシ オブジェクトを実行時に動的に記述できれば、大量のプロキシ クラス コードが削減されるだけでなく、定期的なメンテナンスの手間も軽減されますが、実行時の効率は確実に影響を受けます。このメソッドは次の動的プロキシです。
2. JDK プロキシ
静的プロキシの前提は同じですが、Singer オブジェクトを拡張します
public interface ISinger { void sing(); } /** * 目标对象实现了某一接口 */ public class Singer implements ISinger{ public void sing(){ System.out.println("唱一首歌"); } }
今回は直接テストされます。 Java のレイヤーは実装の詳細をカプセル化しているため (詳しくは後ほど説明します)、コードは非常にシンプルで、形式も基本的に固定されています。
Proxy クラスの静的メソッド newProxyInstance を呼び出すだけです。このメソッドはプロキシ クラス オブジェクトを返します。
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
受け取った 3 つのパラメータは次のとおりです:
●ClassLoader ローダー: 指定します。現在の対象オブジェクトはクラスローダーを使用しており、書き込み方法は固定されています
#● Class6b3d0130bba23ae47fe2b8e8cddf0195[] インターフェース: 対象オブジェクトによって実装されるインターフェースの種類、書き込み方法は固定です●InvocationHandler h: イベント処理インターフェイス、必須 実装クラスに渡します。通常は匿名の内部クラスを直接使用します。テスト コードpublic class Test{ public static void main(String[] args) { Singer target = new Singer(); ISinger proxy = (ISinger) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("向观众问好"); //执行目标对象方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }); proxy.sing(); } }利点: 拡張機能を変更しない拡張機能を動的に実装します。ターゲット オブジェクトのロジック欠点: 静的プロキシと JDK プロキシには共通の欠点があることがわかります。つまり、ターゲット オブジェクトは 1 つ以上のインターフェイスを実装する必要があり、そうでない場合は動的プロキシを実装できません。 3. Cglib エージェント 前提条件: ● cglib の jar ファイルを導入する必要がありますが、Spring のコアパッケージにはすでに Cglib 関数が含まれているので、それを導入することもできます。 spring-core-3.2.5.jar# ターゲット クラスを Final にすることはできません# ターゲット オブジェクトのメソッドが Final/static である場合、インターセプトされません。ターゲットは実行されません。オブジェクトの追加ビジネス メソッド
/** * 目标对象,没有实现任何接口 */ public class Singer{ public void sing() { System.out.println("唱一首歌"); } }
/** * Cglib子类代理工厂 */ public class ProxyFactory implements MethodInterceptor{ // 维护目标对象 private Object target; public ProxyFactory(Object target) { this.target = target; } // 给目标对象创建一个代理对象 public Object getProxyInstance(){ //1.工具类 Enhancer en = new Enhancer(); //2.设置父类 en.setSuperclass(target.getClass()); //3.设置回调函数 en.setCallback(this); //4.创建子类(代理对象) return en.create(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("向观众问好"); //执行目标对象的方法 Object returnValue = method.invoke(target, args); System.out.println("谢谢大家"); return returnValue; } }ここのコードも非常に修正されています。黄色でマークされた部分だけを自分で書く必要があります。Test
/** * 测试类 */ public class Test{ public static void main(String[] args){ //目标对象 Singer target = new Singer(); //代理对象 Singer proxy = (Singer)new ProxyFactory(target).getProxyInstance(); //执行代理对象的方法 proxy.sing(); } }利点: 目標を変更せずに動的に実装できるオブジェクト ロジックの拡張欠点: ターゲットはインターフェイスを実装する必要があります。そうしないと動的プロキシを実現できません概要: それぞれ 3 つのプロキシ モードそれぞれに独自の長所と短所、および対応する適用範囲があり、主に対象オブジェクトがインターフェイスを実装しているかどうかによって決まります。 Spring フレームワークによって選択されたプロキシ モードを例に挙げます。
Spring の AOP プログラミングでは:コンテナに追加されたターゲット オブジェクトに実装インターフェイスがある場合は、JDK プロキシを使用します
Ifターゲット オブジェクトはインターフェイスを実装していません。Cglib プロキシを使用してください
以上がJavaのプロキシとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。