国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Java動態(tài)代理詳解

不定期整理硬盤內(nèi)源代碼、筆記、總結(jié)等,同時發(fā)上來分享一下。今天再發(fā)一篇關(guān)于Java動態(tài)代理的總結(jié)(貌似ItEye一天最多發(fā)5篇Blog,再多只能放草稿箱了?)

-----------------------------------------------------------

Java動態(tài)代理詳解

說到動態(tài)代理,顧名思義就是動態(tài)的代理(真是廢話)。

關(guān)于代理:想必大家都并不陌生,GOF的23種設(shè)計模式之一(結(jié)構(gòu)型模式)。這里暫不多做介紹,有興趣的可以關(guān)注我關(guān)于設(shè)計模式的文章。

什么是動態(tài)代理:

說起動態(tài),其實不如先說什么是靜態(tài)。所謂靜態(tài)代理,個人理解為自己手寫的代理類,或者用工具生成的代理類,或者別人幫你寫的代理類(沒說一樣...)??傊?,就是程序運行前就已經(jīng)存在的編譯好的代理類。

相反,如果代理類程序運行前并不存在,需要在程序運行時動態(tài)生成(無需手工編寫代理類源碼),那就是今天要說的動態(tài)代理了。

如何生成的:根據(jù)Java的反射機制動態(tài)生成。

不多說了,上程序。

目標接口TargetInterface:

Java代碼  
  1. public interface TargetInterface {  
  2.     public int targetMethodA(int number);  
  3.     public int targetMethodB(int number);  
  4. }  

很簡單,一個普通的接口,里面有若干方法(此處寫2個示范一下)

實現(xiàn)該接口的委托類ConcreteClass:

Java代碼  
  1. public class ConcreteClass implements TargetInterface{  
  2.   
  3.     public int targetMethodA(int number) {  
  4.         System.out.println("開始調(diào)用目標類的方法targetMethodA...");  
  5.         System.out.println("操作-打印數(shù)字:"+number);  
  6.         System.out.println("結(jié)束調(diào)用目標類的方法targetMethodA...");  
  7.         return number;  
  8.     }  
  9.       
  10.     public int targetMethodB(int number){  
  11.         System.out.println("開始調(diào)用目標類的方法targetMethodB...");  
  12.         System.out.println("操作-打印數(shù)字:"+number);  
  13.         System.out.println("結(jié)束調(diào)用目標類的方法targetMethodB...");  
  14.         return number;  
  15.     }  
  16.   
  17. }  

很簡單,一個普通的類,實現(xiàn)了目標接口。

代理處理器類ProxyHandler:

Java代碼  
  1. public class ProxyHandler implements InvocationHandler{  
  2.     private Object concreteClass;  
  3.       
  4.     public ProxyHandler(Object concreteClass){  
  5.         this.concreteClass=concreteClass;  
  6.     }  
  7.   
  8.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  9.         System.out.println("proxy:"+proxy.getClass().getName());  
  10.         System.out.println("method:"+method.getName());  
  11.         System.out.println("args:"+args[0].getClass().getName());  
  12.           
  13.         System.out.println("Before invoke method...");  
  14.         Object object=method.invoke(concreteClass, args);//普通的Java反射代碼,通過反射執(zhí)行某個類的某方法  
  15.         //System.out.println(((ConcreteClass)concreteClass).targetMethod(10)+(Integer)args[0]);  
  16.         System.out.println("After invoke method...");  
  17.         return object;  
  18.     }  
  19.   
  20. }  

該類實現(xiàn)了Java反射包中的InvocationHandler接口。代理實例調(diào)用方法時,將對方法調(diào)用指派到它的代理處理器程序的invoke方法中。invoke方法內(nèi)部實現(xiàn)預(yù)處理,對委托類方法調(diào)用,事后處理等邏輯。

最后是入口程序:

Java代碼  
  1. public class DynamicProxyExample {  
  2.     public static void main(String[] args){  
  3.          ConcreteClass c=new ConcreteClass();//元對象(被代理對象)  
  4.          InvocationHandler ih=new ProxyHandler(c);//代理實例的調(diào)用處理程序。  
  5.          //創(chuàng)建一個實現(xiàn)業(yè)務(wù)接口的代理類,用于訪問業(yè)務(wù)類(見代理模式)。  
  6.          //返回一個指定接口的代理類實例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序,如ProxyHandler。  
  7.          TargetInterface targetInterface=  
  8.              (TargetInterface)Proxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),ih);  
  9.          //調(diào)用代理類方法,Java執(zhí)行InvocationHandler接口的方法.  
  10.          int i=targetInterface.targetMethodA(5);  
  11.          System.out.println(i);  
  12.          System.out.println();  
  13.          int j=targetInterface.targetMethodB(15);  
  14.          System.out.println(j);  
  15.     }  
  16. }  

首先創(chuàng)建委托類對象,將其以構(gòu)造函數(shù)傳入代理處理器,代理處理器ProxyHandler中會以Java反射方式調(diào)用該委托類對應(yīng)的方法。然后使用Java反射機制中的Proxy.newProxyInstance方式創(chuàng)建一個代理類實例,創(chuàng)建該實例需要指定該實例的類加載器,需要實現(xiàn)的接口(即目標接口),以及處理代理實例接口調(diào)用的處理器。

最后,調(diào)用代理類目標接口方法時,會自動將其轉(zhuǎn)發(fā)到代理處理器中的invoke方法內(nèi),invoke方法內(nèi)部實現(xiàn)預(yù)處理,對委托類方法調(diào)用,事后處理等邏輯。

 

使用Java動態(tài)代理機制的好處:

1、減少編程的工作量:假如需要實現(xiàn)多種代理處理邏輯,只要寫多個代理處理器就可以了,無需每種方式都寫一個代理類。

2、系統(tǒng)擴展性和維護性增強,程序修改起來也方便多了(一般只要改代理處理器類就行了)。

 

使用Java動態(tài)代理機制的限制:

目前根據(jù)GOF的代理模式,代理類和委托類需要都實現(xiàn)同一個接口。也就是說只有實現(xiàn)了某個接口的類可以使用Java動態(tài)代理機制。但是,事實上使用中并不是遇到的所有類都會給你實現(xiàn)一個接口。因此,對于沒有實現(xiàn)接口的類,目前無法使用該機制。有人說這不是廢話嗎,本來Proxy模式定義的就是委托類要實現(xiàn)接口的?。〉菦]有實現(xiàn)接口的類,該如何實現(xiàn)動態(tài)代理呢?

當然不是沒有辦法,這也是我后面抽時間要繼續(xù)整理和總結(jié)原先使用過的一件神器,相關(guān)Blog會不定期發(fā)上來。那就是大名鼎鼎的CGLib...

PS:CGLib中的動態(tài)代理已經(jīng)新鮮出爐,歡迎訪問:http://shensy.iteye.com/blog/1873155 

 

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JAVA的反射機制與動態(tài)代理
JDK 動態(tài)代理的簡單理解
Java動態(tài)代理的實現(xiàn)
Java 靜態(tài)代理和動態(tài)代理
Java動態(tài)代理機制詳解(JDK 和CGLIB,Javassist,ASM) (清晰,淺顯)
動態(tài)代理模式——JDK動態(tài)代理
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服