1. 程式人生 > >java學習筆記(中級篇)—JDK動態代理

java學習筆記(中級篇)—JDK動態代理

一、什麼是代理模式

相信大家都知道代理商這個概念,在商業中,代理商無處不在。假設你要去買東西,你不可能去找真正的廠家去買,也不可能直接跟廠家提出需求,代理商就是這中間的一橋樑,連線買家和廠商。你要買或者定製什麼產品,需要什麼規格樣式和價格的直接跟代理商溝通就好了,由代理商與真實的廠商溝通,這樣買家有什麼問題都可以諮詢代理商,真實廠商也就可以專心做產品,不需要管其他事務了,買家也插手不了廠商的事。

在以上的關係中,廠商就是被代理物件,代理商就是代理物件,而買家就是呼叫者了。java中有多種動態代理的技術,包括JDK、CGLIB、Javassist等,這裡我會拿CGLIB與JDK動態代理作比較。

二、意義

動態代理的意義就是在與生成一個佔位(代理物件),來代理真實物件,從而達到控制真實物件的目的。要了解動態代理,首先要具備反射的知識。

三、實現動態代理的步驟

代理的實現分為兩個主要步驟:

1.代理物件和真實物件建立代理關係

2.實現代理物件的邏輯方法

四、JDK動態代理

JDK動態代理,JDK自帶的功能,在java.lang.reflect.*包中。要實現JDk動態代理,必須要藉助接口才能產生代理物件。

1.先來定義一個簡單的介面HelloWorld.java

public interface HelloWorld {
    void sayHello();
}

2.HelloWorld的實現類HelloWorldImpl.java

public class HelloWorldImpl implements HelloWorld {
    @Override
    public void sayHello() {
        System.out.println("hello world");
    }
}

3.建立代理關係,必須實現介面InvocationHandler。invoke是接口裡唯一需要實現的方法,裡面實現的代理邏輯,當代理物件排程方法時,就會對映到invoke方法來,實際是通過反射來實現的。而bind()方法就是建立代理關係,通過Proxy的newProxyInstance來建立代理物件,第一個引數類載入器,第二個引數下掛的介面,第三個引數則是實現了代理邏輯方法invoke的類。

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

public class JdkProxy implements InvocationHandler {
    //真實物件
    private Object target = null;

    /**
     * 建立真實物件與代理物件之間的關係
     * @param target 傳入真實物件
     * @return
     */
    public Object bind(Object target){
        this.target = target;
        return Proxy.newProxyInstance
            (target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }

    /**
     *  代理邏輯
     * @param proxy 代理物件
     * @param method 當前排程的方法
     * @param args 排程方法的引數
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("進入代理邏輯方法");
        System.out.println("在呼叫真實物件之前的服務");
        Object object = method.invoke(target,args);
        System.out.println("在呼叫真實物件之後的服務");
        return object;
    }
}

4.測試

import org.junit.Test;

public class JdkProxyTest {

    @Test
    public void test_JdkProxy(){
        JdkProxy proxy = new JdkProxy();
        HelloWorld helloWorld = null;
        try {
            helloWorld = (HelloWorld) proxy
                .bind(Class.forName
            ("com.xcl.ssm.chapter2.jdkproxy.HelloWorldImpl")
                            .newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
        helloWorld.sayHello();
    }
}

五、CGLIB動態代理

上面說JDK動態代理的實現必須藉助接口才能實現,而CGLIB則不用,只需要有一個非抽象類即可。我們以上面的HelloWorldImpl類為例,現在沒有HelloWorld介面了。JDK動態代理必須要實現invocationHandler介面,CGLIB則必須要實現MethodInterceptor介面,裡面也只有一個需要實現的方法intercept(),需要在裡面實現代理邏輯。寫程式碼之前記得導包哦,這是第三方提供的技術。


public class CglibProxy implements MethodInterceptor {

    /**
     *  生成CGLIB代理物件
     * @return
     */
    public Object getProxy(Class clz){
        //CGLIB增強類物件
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clz);
        //設定當前物件為代理邏輯物件
        enhancer.setCallback(this);
        //生成並返回代理物件
        return enhancer.create();
    }

    /**
     *  代理邏輯方法
     * @param proxy 代理物件
     * @param method 方法
     * @param args 引數
     * @param methodProxy 方法代理
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("呼叫真實物件前");
        //通過反射呼叫真實物件的方法
        Object obj = methodProxy.invokeSuper(proxy,args);
        System.out.println("呼叫真實物件後");
        return obj;
    }
}

六、總結

要真正的參透動態代理就要非常熟悉反射機制,從以上的程式碼可以得知,動態代理的底層實現還是基於反射的,我們知道反射是很消耗效能的,這帶來了一些效能問題,但是為了開發上的簡便,這種犧牲是值得的。我們學的框架,比如spring,mybatis等,都大量使用了動態代理技術,有興趣的童鞋可以去閱讀原始碼(表示本人也不是看過很多原始碼),這裡面用到了很多的設計模式,對提高自己的程式碼水平很有幫助。好啦,就說到這裡吧~

喜歡我的小夥伴記得掃描關注呦~

相關推薦

java學習筆記(中級)—JDK動態代理

一、什麼是代理模式 相信大家都知道代理商這個概念,在商業中,代理商無處不在。假設你要去買東西,你不可能去找真正的廠家去買,也不可能直接跟廠家提出需求,代理商就是這中間的一橋樑,連線買家和廠商。你要買或者定製什麼產品,需要什麼規格樣式和價格的直接跟代理商溝通就好了,由代理商與真實的廠商溝通,這樣買家有什麼問題都

java學習筆記(中級)—java實現高質量圖片壓縮

使用java幾十行程式碼實現一個高質量圖片壓縮程式,再也不用去自己找網路的壓縮程式啦!而且很多網上的工具還有水印或者其他的限制,自己動手寫一個簡單的應用,是再合適不過了。 一、實現原理 1、宣告兩個字串變數,分別是要壓縮圖片的路徑和壓縮後圖片的存放路徑 private String brfore_image_

rust學習筆記中級2–結構體與基礎型別成員函式的實現(霜之小刀)

rust學習筆記中級篇2–結構體與基礎型別成員函式的實現(霜之小刀) 歡迎轉載和引用 若有問題請聯絡請聯絡 Email : [email protected] QQ:2279557541 結構體的成員函式的實現 先看個最簡單的示例。

rust學習筆記中級1–泛型(霜之小刀)

rust學習筆記中級篇1–泛型(霜之小刀) 歡迎轉載和引用,若有問題請聯絡 若有疑問,請聯絡 Email : [email protected] QQ:2279557541 結構體泛型 首先上程式碼,如何定義一個泛型的結構體 struc

java基礎:深入理解JDK動態代理

其他更多java基礎文章: java基礎學習(目錄) 經過上一節我們講了Class物件和反射機制,這節就來講一下反射機制在java中的主要應用——動態代理。在講動態代理之前,會先講一下代理模式和靜態代理。 一、代理模式 代理模式是常用的java設計模式,他的特徵是代理類與委託類有同樣的介面,代理類主

java學習筆記————經驗

3.顯示系統當前時間JS程式碼: 放時間的區域: window.onload=function(){ window.setInterval("showTime()", 1000); } function showTime(){ var time = new Date()

java學習筆記————本質7

100.oracle:oracle是甲骨文公司的一個大型資料庫產品,一般在大型專案中應用較多。 比如:銀行、大型企業系統等。和oracle資料庫類似的資料庫還有db2 Oracle資料庫:是一個檔案系統,是物理概念。 安裝: // SCOTT HR 解鎖 例項:

java學習筆記————本質3

9.獲取資源相關方法: 1.獲取真實路徑: servletContext.getRealPath("/WEB-INF/b.txt") ====> String realPath

java學習筆記————本質1

1.HTML:超文字標記語言!不是一種程式語言,是一種描述性的標記語言,用於描述超文字中內容的顯示方式。比如字型、顏色、大小等。 // 顯示資料 JSP也是最終響應回 一個HTML格式頁面來顯示資料! 2.CSS:層疊樣式表!作用:定義網頁的顯示效果。簡單一句話:CS

java學習筆記————本質6

21.3.JSON:是一種輕量級的資料交換格式。 (JavaScript Object Notation) 格式: [{“id”:1,”name”:”吉林省”},{“id”:2,”name”:”遼寧省”}][{'province':'遼寧省'},{'province':

Java學習筆記(1): 從JDK到IDE

什麼是JVM JVM(Java Virtual Machine),即Java虛擬機器。Java是個高階語言,要讓計算機執行程式,必須通過編譯程式的翻譯。不過Java編譯時(原始碼副檔名.java)並不直接編譯為相依於某平臺的0、1序列, 而是翻譯為中介格式的位

Java入門提高】Day11 Java代理——JDK動態代理

創建 pri 建立 ret and etc bool 提高 跳舞   今天來看看Java的另一種代理方式——JDK動態代理   我們之前所介紹的代理方式叫靜態代理,也就是靜態的生成代理對象,而動態代理則是在運行時創建代理對象。動態代理有更強大的攔截請求功能,因為可以獲得類的

java代理模式學習,靜態代理JDK動態代理,CGLIB動態代理

                java代理模式學習,靜態代理,JDK動態代理,CGLIB動態代理   一、理解代理 1、代理,Proxy 。意思是:本來該你做的事兒,別人代替你去做。 比如說:即將

Spring AOP 前(一):Java代理JDK靜態代理JDK動態代理、CGLIB動態代理

Spring AOP 前篇:Java代理之JDK靜態代理、JDK動態代理、CGLIB動態代理 該文章參考多篇文章的基礎上進行了簡化並做少許修改,方便理解。原文章地址如下: Java之代理(jdk靜態代理,jdk動態代理,cglib動態代理,aop,aspectj

Java框架學習_Spring(三)Spring_AOP底層實現:JDK動態代理和Cglib動態代理

AOP和IOC是Spring的兩大思想,AOP即面向切面程式設計,和OOP相輔相成,具體請看: AOP(面向切面程式設計) 這裡學習一下它的底層實現方法----動態代理,動態代理關鍵的是代理,就像你去公司辦事,你有什麼需求,不可能直接找到 boss(原始碼),而是通過祕書(代理)來實現你

Java學習筆記——淺談數據結構與Java集合框架(第一、List)

技術分享 emp 鏈表 adc 下標 -c nod nal integer 橫看成嶺側成峰,遠近高低各不同。不識廬山真面目,只緣身在此山中。               ——蘇軾 這一塊兒學的是雲裏霧裏,咱們先從簡單的入手。逐漸的撥開迷霧見太陽。本次先做List集合的三

JAVA學習筆記系列3-JVM、JRE和JDK的區別

JVM(Java Virtual Machine)就是一個虛擬的用於執行bytecode位元組碼的“虛擬計算機”。它和os打交道 JRE(Java Runtime Environment)包含:Java虛擬機器、庫函式、執行java應用程式所必須的檔案。它包含了JVM JDK(Java Developme

Java,JDK動態代理的原理分析

1. 代理基本概念:   以下是代理概念的百度解釋:代理(百度百科)        總之一句話:三個元素,資料--->代理物件--->真實物件;複雜一點的可以理解為五個元素:輸入資料--->代理物件--->真實物件--->代理物件---

Java架構-Java JDK 動態代理

代理模式是常用的java設計模式,他的特徵是代理類與委託類有同樣的介面,代理類主要負責為委託類預處理訊息、過濾訊息、把訊息轉發給委託類,以及事後處理訊息等。代理類與委託類之間通常會存在關聯關係,一個代理類的物件與一個委託類的物件關聯,代理類的物件本身並不真正實現服務,而是通過呼叫委託類的物件的相關方法,來提供

8.3(java學習筆記動態編譯(DynamicCompiler)與動態執行(DynamicRun)

一、動態編譯   簡單的說就是在執行一個java程式的過程中,可以通過一些API來編譯其他的Java檔案。   下面主要說動態編譯的實現:   1、獲取java編譯編譯器   2、執行編譯器(須指定編譯檔案)   獲取編譯器通過JavaCompiler ToolProvider.getSystemJ