搜尋
首頁Javajava教程Java怎麼透過動態代理實現一個簡單的攔截器操作

一、代理

在使用動態代理實作攔截器之前我們先簡單了解一下什麼Java的代理程式。

代理,顧名思義,就是不直接操作被代理(下面都用目標對象稱呼,聽起來舒服一些)對象,而是透過一個代理對象去間接的使用目標對像中的方法。代理分為兩種模式,一種是靜態代理,一種是動態代理。接下來先寫一個靜態代理的例子。

無論是靜態代理還是動態代理,目標物件(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)定義一個目標物件類別(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

----target class---class com.jd.pattern.proxy.dynamicProxy.UserDao
----target interfaces---[Ljava.lang.Class;@1fb3ebeb
----proxy----:class com.sun.proxy.$Proxy0
----開始交易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中文網其他相關文章!

陳述
本文轉載於:亿速云。如有侵權,請聯絡admin@php.cn刪除
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具