ホームページ  >  記事  >  Java  >  Javaプロキシモードを適用する方法

Javaプロキシモードを適用する方法

WBOY
WBOY転載
2023-05-06 12:52:061074ブラウズ

1. エージェンシー モデルの紹介

エージェンシー モデルとは、実際には代わりの人を見つけることです。何かをやりたい場合、自分でやらない場合は、それをやってくれる人を見つけてください。これが代理店モデルです。プログラムでは、オブジェクトの代わりに代替物を用意し、その代替物が目的のオブジェクトにアクセスするように制御しますが、これの利点は、目的のオブジェクトが提供する機能に加えて、代替物がより多くの作業を実行できることです。 、対象オブジェクトの機能を拡張できます。プロキシは、リモート オブジェクト、作成にコストがかかるオブジェクト、またはセキュリティ制御が必要なオブジェクトの場合があります。

プロキシ モードは、主に次の 3 種類に分類されます。

  • 静的プロキシ

  • ##動的プロキシ (JDK プロキシとも呼ばれます) 、インターフェイス エージェント)

  • cglib エージェント (動的エージェントのカテゴリにも属します)

2. 静的エージェント

1. 静的プロキシの概要: "

静的プロキシを使用する場合、インターフェイスまたは親クラスを定義する必要があります。プロキシ オブジェクトとプロキシ オブジェクトは同じインターフェイスを実装するか、継承する必要があります。同じ親クラスです。

『2. アプリケーション例:』

  • インターフェースを定義します。

    TeacherDao

  • プロキシ オブジェクトを定義します。

    TeacherDaoImpl、実装する必要があります TeacherDao

  • プロキシ オブジェクトを定義します。

    TeacherDaoProxy も実装する必要があります TeacherDao

  • 電話する

    TeacherDaoImpl メソッド、最初に作成する必要があります TeacherDaoProxy オブジェクトを作成し、 TeacherDaoImpl オブジェクト、 TeacherDaoImplオブジェクトが渡されました TeacherDaoProxy オブジェクトを呼び出し、関連するメソッドを呼び出します。

コード実装:
  • TeacherDao.java:

  • えー
  • TeacherDaoImpl.java:

<code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
  • TeacherDaoProxy.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
  • Client.java: プロキシ オブジェクトを呼び出します

<code>public class TeacherDaoProxy implements TeacherDao {<br>    <br>    private TeacherDao target; // 被代理的对象<br>    <br>    public TeacherDaoProxy(TeacherDao target){<br>        this.target = target;<br>    }<br>    <br>    @Override<br>    public void teach() {<br>        System.out.println("代理开始");<br>        // 这里可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的前置通知<br>        target.teach();<br>        // 这里也可以写一些额外的逻辑,以达到扩展被代理对象的目的,相当于spring的后置通知<br>        System.out.println("代理结束");<br>    }<br>}<br></code>

『3. 静的プロキシの長所と短所:』

  • 利点: プロキシ オブジェクトを変更せずに拡張できます。いくつかの機能強化

  • 欠点: 同じインターフェイスを実装するか、同じ親クラスを継承する必要があるため、多くのプロキシ クラスが存在し、インターフェイスまたは親クラスが変更されると、プロキシ オブジェクトとプロキシ オブジェクトが作成されます。両方ともメンテナンスが必要です

3. 動的プロキシ (JDK プロキシ)

「1. 動的プロキシの概要:」

プロキシ オブジェクト インターフェイスを実装しませんが、プロキシ オブジェクトはインターフェイスを実装する必要があります。動的プロキシ オブジェクトの生成では、JDK API とリフレクション パッケージの Proxy クラスを使用して、メモリ内にプロキシ オブジェクトを動的に構築します。

『2.java.lang.reflect.Proxy:』

このクラスには、次の 3 つのパラメータを受け取る

newProxyInstance メソッドがあります。 : rree

『3. アプリケーション例:』

  • インターフェースを定義します: TeacherDao

  • プロキシ オブジェクトを定義します: TeacherDaoImpl、TeacherDao

  • プロキシ ファクトリ ProxyFactory を定義します。getProxyInstance メソッドがあります。プロキシ オブジェクトを渡し、プロキシ オブジェクト インスタンスを返し、呼び出します。プロキシ オブジェクト メソッド

コード実装:
  • TeacherDao.java:

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDao target = new TeacherDaoImpl();<br>        // 创建代理对象<br>        TeacherDaoProxy proxy = new TeacherDaoProxy(target);<br>        // 通过代理对象调用方法<br>        proxy.teach();<br>    }<br>}<br></code>
を介したプロキシ オブジェクト
  • TeacherDaoImpl.java:

<code>static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)<br></code>
  • ProxyFactory.java

<code>public interface TeacherDao {<br>    void teach();<br>}<br></code>
  • Client.java: プロキシ経由でメソッドを呼び出す

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
4. cglib プロキシ

「1. cglib プロキシの概要」 : 』

静的プロキシと動的プロキシでは、プロキシされるオブジェクトはインターフェイスを実装する必要があります。クラスがインターフェイスを実装していない場合は、cglib プロキシを使用する必要があります。 cglib エージェントはサブクラス エージェントとも呼ばれ、メモリ内にサブクラス オブジェクトを構築してプロキシ オブジェクトを拡張します。 cglib エージェントの最下層は、ASM と呼ばれるバイトコード処理フレームワークを使用してバイトコードを変換し、エージェントを実装するための新しいクラスを生成します。プロキシされたクラスを最終クラスにすることはできません。そうでない場合は、エラーが報告されます。プロキシ オブジェクトのメソッドが Final/static である場合、それはインターセプトされません。つまり、プロキシ オブジェクトの追加のビジネス メソッドは実行されません。

『2. 応用例:』

  • 首先要添加cglib相关依赖:

<code><dependency><br>     <groupId>cglib</groupId><br>     <artifactId>cglib</artifactId><br>     <version>3.3.0</version><br></dependency><br></code>
 
  • TeacherDaoImpl.java:

<code>public class TeacherDaoImpl implements TeacherDao {<br>    @Override<br>    public void teach() {<br>        System.out.println("今天又是没妹子的一天(ノへ ̄、)");<br>    }<br>}<br></code>
 
  • CglibProxyFactory.java:

<code>// 需要实现MethodInterceptor并重写其方法<br>public class CglibProxyFactory implements MethodInterceptor {<br><br>    private Object target;<br><br>    public CglibProxyFactory(Object target){<br>        this.target = target;<br>    }<br><br>    /**<br>     * 返回target的代理对象<br>     * @return<br>     */<br>    public Object getProxyInstance(){<br>        // 1. 创建工具类<br>        Enhancer enhancer = new Enhancer();<br>        // 2. 设置父类<br>        enhancer.setSuperclass(target.getClass());<br>        // 3. 设置回调函数<br>        enhancer.setCallback(this);<br>        // 4. 创建子类对象,即代理对象<br>        return enhancer.create();<br>    }<br>    @Override<br>    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {<br>        System.out.println("CGLIB代理开始");<br>        Object returnValue = method.invoke(target, args);<br>        System.out.println("CGLIB代理结束");<br>        return returnValue;<br>    }<br>}<br></code>
 
  • Client.java:通过代理调用方法

<code>public class Client {<br><br>    public static void main(String[] args){<br>        // 创建被代理的对象<br>        TeacherDaoImpl target = new TeacherDaoImpl();<br>        // 获取代理对象,并将被代理对象传给代理对象<br>        TeacherDaoImpl proxy = (TeacherDaoImpl) new CglibProxyFactory(target).getProxyInstance();<br>        // 执行方法,触发intecept方法,从而实现执行被代理对象的方法<br>        proxy.teach();<br>    }<br>}<br></code>

以上がJavaプロキシモードを適用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。