- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- Java基礎之讓你徹底搞懂代理模式
什么是代理模式?
先來(lái)生活常用例子:你想買(mǎi)票,你沒(méi)必要去車(chē)站買(mǎi);而是可以去一個(gè)代售點(diǎn),代售點(diǎn)代理車(chē)站賣(mài)票,這就是一個(gè)簡(jiǎn)單的代理模式!
顧名思義,靜態(tài)的,由程序員構寫(xiě),在編譯是就已經(jīng)將程序接口,代理類(lèi)和被代理類(lèi)寫(xiě)定了!在程序運行前就已經(jīng)生成!
來(lái)個(gè)簡(jiǎn)單實(shí)例:
設計公共接口Person:
public interface Person { public void handinWork(); }
Student:
public class Student implements Person { private String name; public Student(String name) { this.name=name; } public void setName(String name) { this.name = name; } public void handinWork() { System.out.println(name+"提交作業(yè)"); } }
代理類(lèi)StudentProxy:
public class StudentProxy implements Person { //代理誰(shuí) Student student; //防止重名,確保只是代理Student這個(gè)對象 public StudentProxy(Student student) { if(student.getClass()==Student.class){ this.student = (Student) student; } } public void handinWork() { //交作業(yè)時(shí)代理(班長(cháng))想代替學(xué)生搞點(diǎn)事··· System.out.println("老師這個(gè)比的作業(yè)是抄的呢"); student.handinWork(); } }
測試:
public class StaticProxy { public static void main(String[] args) { //創(chuàng )建出兩個(gè)對象,代理和被代理 Student student = new Student("張三"); StudentProxy monitor = new StudentProxy(student); //代理類(lèi)去交作業(yè)?。。。?! monitor.handinWork(); } }
可以發(fā)現,程序本質(zhì)還是學(xué)生交作業(yè),不過(guò)是通過(guò)一個(gè)中間層monitor(班長(cháng))去實(shí)現的,然后這個(gè)代理層還可以添加些其他的操作功能,在提交作業(yè)之前或者之后!
靜態(tài)代理是在程序運行前就生成了,很明顯動(dòng)態(tài)代理就是在程序運行期間添加代理層以達到效果。代理類(lèi)動(dòng)態(tài)生成!
舉個(gè)例子:方便理解,就上面那個(gè)實(shí)例我們將它改造成一個(gè)動(dòng)態(tài)的!
第一步,創(chuàng )建一個(gè)類(lèi)實(shí)現InvocationHandler接口,用它構建出代理類(lèi)和代理方法:
public class ProxyInvocation implements InvocationHandler { //被代理的接口,真實(shí)的對象 private Person person; //生成得到的代理類(lèi) public void setPerson(Person person) { this.person = person; } //通過(guò)Proxy類(lèi)的newProxyInstance方法創(chuàng )建代理對象,我們來(lái)看下方法中的參數 // * 第一個(gè)參數:people.getClass().getClassLoader(),使用handler對象的classloader對象來(lái)加載我們的代理對象 // * 第二個(gè)參數:people.getClass().getInterfaces(),這里為代理類(lèi)提供的接口是真實(shí)對象實(shí)現的接口,這樣代理對象就能像真實(shí)對象一樣調用接口中的所有方法 // * 第三個(gè)參數:handler,我們將代理對象關(guān)聯(lián)到上面的InvocationHandler對象上 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),person.getClass().getInterfaces(),this); } //處理代理實(shí)例,返回結果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; } }
參照靜態(tài)代理,需要一個(gè)代理對象,只不過(guò)靜態(tài)代理中代理對象是我們手動(dòng)創(chuàng )建的,所以動(dòng)態(tài)代理中我們利用jdk自帶代理類(lèi)Proxy的newProxyInstance方法動(dòng)態(tài)的生成了一個(gè)代理類(lèi)而已,這個(gè)代理類(lèi)可以根據我們傳的參數動(dòng)態(tài)改變,
測試:
//真實(shí)角色student Student student = new Student("張三"); //拿到InvocationHandler的繼承類(lèi) ProxyInvocation pih = new ProxyInvocation(); //拿到代理的接口 pih.setPerson(student); //動(dòng)態(tài)生成了proxy代理類(lèi) Person proxy = (Person) pih.getProxy(); //代理類(lèi)執行方法 proxy.handinWork();
改進(jìn)成工具類(lèi):將獲得接口部分全部采用參數代替;
private Object target; //生成得到的代理類(lèi) public void setPerson(Object target) { this.target= target; } //通過(guò)Proxy類(lèi)的newProxyInstance方法創(chuàng )建代理對象,我們來(lái)看下方法中的參數 // * 第一個(gè)參數:people.getClass().getClassLoader(),使用handler對象的classloader對象來(lái)加載我們的代理對象 // * 第二個(gè)參數:people.getClass().getInterfaces(),這里為代理類(lèi)提供的接口是真實(shí)對象實(shí)現的接口,這樣代理對象就能像真實(shí)對象一樣調用接口中的所有方法 // * 第三個(gè)參數:handler,我們將代理對象關(guān)聯(lián)到上面的InvocationHandler對象上 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } //處理代理實(shí)例,返回結果 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(person, args); return result; }
就是把接口類(lèi)型和參數改一下就可以!后續會(huì )添加代理模式在Spring上的使用,
你不敲一遍代碼你永遠都不會(huì )理解,你抱著(zhù)學(xué)一遍而不是徹底弄明白你也不可能學(xué)會(huì )!多查資料多理解代碼,多花點(diǎn)時(shí)間一定會(huì )懂得!加油老鐵。以解決問(wèn)題的心態(tài)學(xué)編程而不是為了高薪工作。
到此這篇關(guān)于Java基礎之讓你徹底搞懂代理模式的文章就介紹到這了,更多相關(guān)java代理模式內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站