目次
1. プロキシ
(1) まずインターフェイスを定義します
(2) ターゲット オブジェクト (target) を定義します
(3) プロキシ オブジェクトを定義します
ホームページ Java &#&チュートリアル 動的プロキシを介して Java で単純なインターセプタ操作を実装する方法

動的プロキシを介して Java で単純なインターセプタ操作を実装する方法

Apr 30, 2023 pm 08:55 PM
java

1. プロキシ

動的プロキシを使用してインターセプタを実装する前に、まず Java プロキシとは何かを簡単に理解しましょう。

エージェントは、その名前が示すように、プロキシされるオブジェクト (以下、ターゲット オブジェクトと呼びます。この方がわかりやすいでしょう) を直接操作するのではなく、プロキシ オブジェクトを通じて間接的にターゲット オブジェクト内のメソッドを使用します。エージェントは 2 つのモードに分けられ、1 つは静的エージェント、もう 1 つは動的エージェントです。次に、静的プロキシの例を作成します。

静的プロキシでも動的プロキシでも、ターゲット オブジェクト (target) はインターフェイス (interface) を実装する必要があります。ただし、cglib が提供するプロキシを使用する場合は、インターフェイスを実装する必要はありませんですが、サブクラスを介して実装されているため、このメソッドについては今のところ説明しません。

(1) まずインターフェイスを定義します

public interface IUserDao {
    void save();
}
ログイン後にコピー

(2) ターゲット オブジェクト (target) を定義します

public class UserDaoImpl implements IUserDao {
    public void save() {
        System.out.println("--------已经保存数据---------");
    }
}
ログイン後にコピー

(3) プロキシ オブジェクトを定義します

public class UserDaoProxy implements IUserDao {
 private IUserDao target;//将目标对象放到代理对象中
 public UserDaoProxy(IUserDao target){
  this.target = target;
  }
 public void save() {
     System.out.println("------开始事务------");
            target.save();
     System.out.println("-------提交事务------");
    }
}
ログイン後にコピー

次のテスト:

public class Test {
public static void main(String[] args){
    IUserDao userDao = new UserDaoImpl();
    UserDaoProxy proxy = new UserDaoProxy(userDao);
    proxy.save();//通过代理对象调用save方法
    }
}
ログイン後にコピー

出力結果は次のとおりです:

------トランザクションの開始------
--------データは保存されました --------

----------トランザクションのコミット-----

#このメソッドには問題がありますつまり、プロキシ オブジェクトは、プロキシ オブジェクトによって実装されるのと同じインターフェイスを実装する必要があり、深刻な結合につながります。したがって、以下では、動的プロキシ (jdk プロキシ) という改良された方法が使用されます。

動的プロキシ メソッドでは、ターゲット オブジェクト (target) にもインターフェイスを実装する必要があります。

(1) インターフェイス (IUserDao) を定義します。

(2) ターゲット オブジェクトを定義します。 class (UserDaoImpl )

(3) 動的プロキシ クラスを作成します

public class ProxyFactory {
    //维护一个目标对象
    private Object target; 
    public ProxyFactory(Object target) {
        this.target = target;
    }
 
    //给目标对象生成代理对象
    public Object getProxyInstance() {
        System.out.println("----target class---" + target.getClass());
        System.out.println("----target interfaces---" +
            target.getClass().getInterfaces());
 
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                    System.out.println("----开始事务2-----");
 
                    //执行目标对象方法
                    Object returnValue = method.invoke(target, args);
                    System.out.println("----提交事务2----");
 
                    return returnValue;
                }
            });
    }
}
ログイン後にコピー
テストします:

public class Test {
    public static void main(String[] args) {
        //目标对象
        IUserDao target = new UserDao();
        System.out.println(target.getClass());
 
        //给目标对象创建代理对象
        IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
        System.out.println("----proxy----:" + proxy.getClass());
        proxy.save();
        proxy.delete();
    }
}
ログイン後にコピー
出力結果:

class com. jd.pattern.proxy.dynamicProxy.UserDao

----ターゲット クラス---クラス com.jd.pattern.proxy.dynamicProxy.UserDao
----ターゲット インターフェイス---[Ljava.lang.クラス;@1fb3ebeb
----プロキシ----: クラス com.sun.proxy.$Proxy0
----トランザクション 2 を開始-----
-----保存完了--- ---
----トランザクション 2 を送信-----
----トランザクション 2 を開始-----
----削除完了 ----

------トランザクション 2 を送信------

2. 動的プロキシを使用して単純なインターセプタを実装する

動的プロキシ メソッドが使用されるため、インターフェイス、ターゲット クラス、プロキシ クラス、およびインターセプターになります。

1. インターフェイスを定義します

public interface BusinessFacade {
    void doSomething();
}
ログイン後にコピー

2. ターゲット オブジェクトを定義します

public class BusinessClass implements BusinessFacade {
    public void doSomething() {
        System.out.println("在业务组件BusinessClass中调用doSomething方法");
    }
}
ログイン後にコピー

3. インターセプターを作成します

public class InterceptorClass {
    public void before() {
        System.out.println("在InterceptorClass中调用方法:before()");
    }
 
    public void after() {
        System.out.println("在InterceptorClass中调用方法:after()");
    }
}
ログイン後にコピー

4. プロキシを作成します

public class DynamicProxyHandler {
    //声明被代理对象
    private Object target;
    //创建拦截器
    InterceptorClass interceptor = new InterceptorClass();
    //动态生成一个代理对象,并绑定被代理类和代理处理器
    public Object getProxyInstance(final Object target) {
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            new InvocationHandler() {
                public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                    interceptor.before();
                    Object result = method.invoke(target, args);
                    interceptor.after();
                    return result;
                }
            });
    }
}
ログイン後にコピー

テストします:

public class Test {
    public static void main(String[] args) {
        //创建动态代理工具
        DynamicProxyHandler proxyHandler = new DynamicProxyHandler();
        //创建业务组件
        BusinessFacade target = new BusinessClass();
        //获取代理对象
        BusinessFacade proxy = (BusinessFacade) proxyHandler.getProxyInstance(target);
        //通过代理对象调用目标对象方法
        proxy.doSomething();
    }
}
ログイン後にコピー
出力結果:

InterceptorClass のメソッドを呼び出します: before()

ビジネス コンポーネント BusinessClass の doSomething メソッドを呼び出します。
InterceptorClass のメソッドを呼び出します: after()

以上が動的プロキシを介して Java で単純なインターセプタ操作を実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Javaの平方根 Javaの平方根 Aug 30, 2024 pm 04:26 PM

Java の平方根のガイド。ここでは、Java で平方根がどのように機能するかを、例とそのコード実装をそれぞれ示して説明します。

Javaの完全数 Javaの完全数 Aug 30, 2024 pm 04:28 PM

Java における完全数のガイド。ここでは、定義、Java で完全数を確認する方法、コード実装の例について説明します。

Java の乱数ジェネレーター Java の乱数ジェネレーター Aug 30, 2024 pm 04:27 PM

Java の乱数ジェネレーターのガイド。ここでは、Java の関数について例を挙げて説明し、2 つの異なるジェネレーターについて例を挙げて説明します。

ジャワのウェカ ジャワのウェカ Aug 30, 2024 pm 04:28 PM

Java の Weka へのガイド。ここでは、weka java の概要、使い方、プラットフォームの種類、利点について例を交えて説明します。

Javaのスミス番号 Javaのスミス番号 Aug 30, 2024 pm 04:28 PM

Java のスミス番号のガイド。ここでは定義、Java でスミス番号を確認する方法について説明します。コード実装の例。

Java Springのインタビューの質問 Java Springのインタビューの質問 Aug 30, 2024 pm 04:29 PM

この記事では、Java Spring の面接で最もよく聞かれる質問とその詳細な回答をまとめました。面接を突破できるように。

Java 8 Stream Foreachから休憩または戻ってきますか? Java 8 Stream Foreachから休憩または戻ってきますか? Feb 07, 2025 pm 12:09 PM

Java 8は、Stream APIを導入し、データ収集を処理する強力で表現力のある方法を提供します。ただし、ストリームを使用する際の一般的な質問は次のとおりです。 従来のループにより、早期の中断やリターンが可能になりますが、StreamのForeachメソッドはこの方法を直接サポートしていません。この記事では、理由を説明し、ストリーム処理システムに早期終了を実装するための代替方法を調査します。 さらに読み取り:JavaストリームAPIの改善 ストリームを理解してください Foreachメソッドは、ストリーム内の各要素で1つの操作を実行する端末操作です。その設計意図はです

Java での日付までのタイムスタンプ Java での日付までのタイムスタンプ Aug 30, 2024 pm 04:28 PM

Java での日付までのタイムスタンプに関するガイド。ここでは、Java でタイムスタンプを日付に変換する方法とその概要について、例とともに説明します。

See all articles