1. 程式人生 > >如何通俗易懂的理解JAVA的動態代理模式

如何通俗易懂的理解JAVA的動態代理模式

首先,本文是對https://blog.csdn.net/briblue/article/details/73928350的一個小結,適合小白看,歡迎大家去該地址閱讀。

而且要理解動態代理,需要對於java反射的概念有所瞭解,不瞭解的同學可以先去了解下反射的基礎概念。

什麼是代理

首先 代理,從漢語去理解的話,就是我本來自己一個人能做的事,我不親自去做,讓另一個人幫我做。這個人就是代理。

比如,我現在要物件A執行一個方法B,對於最基本的Java程式碼肯定就是直接A.B().

這樣肯定是可以實現的。但是存在什麼問題呢?

存在的問題

如果我現在要加入操作:比如我要求我在B方法之前我要先實現一小段功能F1,在B之前實現一小段功能F2。

例如:F1為輸出“開始了”,F2為輸出“結束了”,該如何做?

解決辦法

也許有人會問,這還不簡單,開啟B方法原始碼,在方法開頭syso,在方法後面syso,輕輕鬆鬆,我幹嘛還要學動態代理,難道是嫌程式設計師太閒了? 當然不是,修改原始碼固然在功能上是可行的,你能夠每次功能改變都去修改原始碼嗎?而且你知識syso一下還好,如果是一大段程式碼呢?你原始碼的維護是不是很困難?

所以,我們才會有代理的思想,就是說,我不修改你原始碼了,我讓一個“中間類”來辦這件事,來呼叫你的方法,然後我在中間類中,我想怎麼實現,想怎麼新增都行。這樣是不是極大的保護了原始碼,而且下次你功能優點變化,我修改修改代理類,實在不行,我重新定義一個代理類,這樣的維護成本是不是比你直接修改原始碼要強?這就是AOP(面向切面程式設計);

實現

那現在來實現,實現程式碼在開頭的文章有,大家可以看一下。

本文主要就是對該文章的一個補充,下面解釋下,我在學習過程中遇到的難點。

Proxy.newProxyInstance(MaoTaiJiu.class.getClassLoader(),MaoTaiJiu.class.getInterfaces(), handler);

這是一個靜態方法,主要是建立一個動態代理。那麼既然是代理,被代理的類是哪一個呢?這裡就是反射的概念。因為被代理的物件有很多很多,不可能挨個去寫一個代理方法,因此我們利用反射原理。我既然要代理,那麼我這個代理裡面一定要有這個物件。就是說,我櫃檯必須要有酒才能賣酒。因此,在代理裡面我必定要有一個酒的屬性,但是,如何建立?那按照反射思想,我傳進這個類的一個構造器,那麼我就可以建立這個類的物件,從而可以呼叫其中的方法。問題又來了,我根本不知道介面名稱啊,怎麼呼叫。那就用反射來獲得這個類要代理的介面,本例只有一個方法,所以全部即可;handler,即為InvocationHandler 物件,即繼承 該類的代理類,該類的invoke方法主要就是實現代理功能,其中method.invoke()就是反射原理中去執行你之前傳入方法。然後你可以實現自己的操作。最終返回一個Object物件,你可以cast為任意物件,最好為介面型別。體現面向介面程式設計,然後用該介面物件呼叫方法即可實現功能。

如有錯誤,請指正,多謝。