代理模式-jdk動態代理

来源:https://www.cnblogs.com/yangyanbo/archive/2020/02/27/12370110.html
-Advertisement-
Play Games

IDB package com.bjpowernode.proxy; /** * 代理類和目標類都必須使用同一個介面。 */ public interface IDB { int insert(); int delete(); int update(); } OracleDB package com ...


IDB 

package com.bjpowernode.proxy;

/**
 * 代理類和目標類都必須使用同一個介面。 
 */
public interface IDB {
    
    int insert();
    int delete();
    int update();
}

OracleDB 

package com.bjpowernode.proxy;

/**
 * 這是一個Oracle資料庫相關的操作類
 * 
 * 目標類(委托類)。
 */
public class OracleDB implements IDB{
    public int insert(){
        
        //以下是一個插入操作
        System.out.println("Oracle insert data....");
        try {
            Thread.sleep(526);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return 0;
    }
    
    
    public int delete(){
        
        //以下是一個刪除操作
        System.out.println("Oracle delete data....");
        try {
            Thread.sleep(569);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        return 0;
    }
    
    
    public int update(){
        
        //以下是一個更新操作
        System.out.println("Oracle update data....");
        try {
            Thread.sleep(456);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
        return 0;
    }
    
}

TimeInvocationHandler 

package com.bjpowernode.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 註冊在這個介面中的代碼,在代理對象調用代理方法的時候,自動執行。
 * 我們的擴展代碼就註冊在這個類中。
 */
public class TimeInvocationHandler implements InvocationHandler {

    //這個程式運行期,obj引用中保存了記憶體地址指向的對象是一個目標對象。
    private Object obj;
    
    public TimeInvocationHandler(Object obj){
        this.obj = obj;
    }
    
    /**
     * proxy 是代理對象的引用。
     * method 是目標類中的目標方法
     * args 是目標類中的目標方法的實參
     */
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        
        long begin = System.currentTimeMillis();
        
        //通過反射機制去調用目標類中的目標方法
        Object retValue = method.invoke(obj, args);
        
        long end = System.currentTimeMillis();
        System.out.println("方法執行所耗費" + (end-begin) + "毫秒");
        
        return retValue;
    }

}

Test 

package com.bjpowernode.proxy;

import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args) {
        
        //創建目標類對象
        IDB db = new OracleDB();
        
        //創建代理對象
        //DBProxy dbProxy = new DBProxy(); //這是靜態代理模式中創建對象,因為DBProxy是我們程式員手動編寫的。
        
        //創建代理對象(這次創建代理對象是交給JVM完成,包括在這個過程中,JVM也會自動生成“代理類的位元組碼”)
        //這個代理類是動態生成的位元組碼不會以.class文件的形式保存在硬碟上,所以我們稱作動態代理。
        
        //第一個參數是類裝載器:JVM會在記憶體中自動生成一個位元組碼,但是這個位元組碼要想運行,必須經過類裝載器的裝載
        //然後進一步解析,所以必須傳遞一個類裝載器,這個類裝載器就是用來裝載這個臨時的“位元組碼”。
        //代理類和目標類必須使用同一個類裝載器。
        
        //第二個參數:是JVM在生成代理類的時候需要實現介面,但是這個介面又不能隨便寫,因為代理類和目標類要求實現相同的介面。
        //所以我們將目標類實現的介面獲取到之後傳遞過來就行了。
        //JDK中提供的代理模式只能代理介面。如果目標類它的父類型不是一個介面而是一個抽象類,那麼JDK中提供的動態代理就不能用了,需要使用
        //第三方組件,例如:cglib。
        
        //第三個參數:是InvocationHandler,這是一個介面,這個介面中的方法會在代理類調用代理方法的時候自動執行。
        IDB dbProxy = (IDB)Proxy.newProxyInstance(db.getClass().getClassLoader(), db.getClass().getInterfaces(), new TimeInvocationHandler(db));
        
        
        //通過代理對象中的方法去執行目標對象中的方法。
        dbProxy.insert(); //dbProxy是一個動態生成的代理對象,由於這個代理對象實現了和OracleDB一樣的介面,所以可以用IDB介面指向JVM中的代理對象。
        dbProxy.delete(); // 這裡調用的delete方法是是代理類中的代理方法,不是目標類中的目標方法。但是一定會通過代理方法去調用目標方法。
        dbProxy.update();
        
    }

}

 

  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ,js的運算符分為算數,賦值,比較和邏輯運算符;常見的算數有:+ - * / %(加減乘除,取模),比方說5/4=4*1+1;5%4=1,js算數順序:從左往右,先* / %後+ ;js的值包含數字,字元串,布爾值;在算數運算中,“加號”:有字元串,按照字元串處理,沒有按照數字處理;註意布爾值fa... ...
  • 獲取滑鼠位置及滑鼠單擊了哪個按鍵。private void GetMousePoint(){ Point ms = Control.MousePosition; this.label2.Text = string.Format("當前滑鼠位置:{0}:{1}", ms.X, ms.Y); Mouse... ...
  • Eureka集群的搭建 上次說過了在SpringCloud應用中使用Eureka註冊中心,用來對服務提供者進行服務註冊與發現,但同時,它也是一個“微服務”,單個應用使用空間有限,因此和zookeeper一樣,它也需要搭建集群(Cluster)。 搭建Eureka集群的原理就是創建多個eureka應用 ...
  • 使用Ribbon進行負載均衡 在使用Ribbon之前,我們先想一個之前的問題,之前我們將服務提供者註冊進了eureka註冊中心,但是在消費者端,我們還是使用的restTemplate調用的時候,其中寫的還是http://localhost:8001這樣的調用方式,是不是有一些不妥呢?是不是應用像du ...
  • 本篇文章主要是手把手教你搭建 ELK 實時日誌分析平臺,那麼,ELK 到底是什麼呢? ELK 是三個開源項目的首字母縮寫,這三個項目分別是:Elasticsearch、Logstash 和 Kibana。 Elasticsearch 是一個 搜索和分析引擎 。 Logstash 是 伺服器端數據處理 ...
  • jdk的動態代理只可以為介面去完成操作,而cglib它可以為沒有實現介面的類去做代理,也可以為實現介面的類去做代理。 IDB package com.bjpowernode.proxy; /** * 代理類和目標類都必須使用同一個介面。 */ public interface IDB { int i ...
  • 學習筆記(Python繼承) 有幾種叫法(父類-子類、基類-派生類)先拿代碼演示一下: 1 class father: 2 def work(self): 3 print("work>>>>>") 4 5 def car(self): 6 print("car>>>>>>>>>") 7 8 clas ...
  • 什麼是正則? 正則表達式也稱為正則,是一個特殊的字元序列,能幫助檢查一個字元串是否與某種模式匹配。可以用來進行驗證:郵箱、手機號、qq號、密碼、url = 網站地址、ip等。正則不是python語言獨有的技術,python語言直到1.5版本才將正則表達式完成的整理/納入進re模塊中,我們只需要導入r ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...