一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

java動態(tài)代理(JDK和cglib)

 java_laq小館 2013-07-24

java動態(tài)代理(JDK和cglib)

JAVA的動態(tài)代理 
代理模式 
代理模式是常用的java設(shè)計(jì)模 式,他的特征是代理類與委托類有同樣的接口,代理類主要負(fù)責(zé)為委托類預(yù)處理消息、過濾消息、把消息轉(zhuǎn)發(fā)給委托類,以及事后處理消息等。代理類與委托類之間 通常會存在關(guān)聯(lián)關(guān)系,一個(gè)代理類的對象與一個(gè)委托類的對象關(guān)聯(lián),代理類的對象本身并不真正實(shí)現(xiàn)服務(wù),而是通過調(diào)用委托類的對象的相關(guān)方法,來提供特定的服 務(wù)。 
按照代理的創(chuàng)建時(shí)期,代理類可以分為兩種。 
靜態(tài)代理:由程序員創(chuàng)建或特定工具自動生成源代碼,再對其編譯。在程序運(yùn)行前,代理類的.class文件就已經(jīng)存在了。 
動態(tài)代理:在程序運(yùn)行時(shí),運(yùn)用反射機(jī)制動態(tài)創(chuàng)建而成。 

 

首先看一下靜態(tài)代理: 
1、Count.java 

Java代碼 
  1. package net.battier.dao;  
  2.   
  3. /** 
  4.  * 定義一個(gè)賬戶接口 
  5.  *  
  6.  * @author Administrator 
  7.  *  
  8.  */  
  9. public interface Count {  
  10.     // 查看賬戶方法  
  11.     public void queryCount();  
  12.   
  13.     // 修改賬戶方法  
  14.     public void updateCount();  
  15.   
  16. }  


2、CountImpl.java 

Java代碼 
  1. package net.battier.dao.impl;  
  2.   
  3. import net.battier.dao.Count;  
  4.   
  5. /** 
  6.  * 委托類(包含業(yè)務(wù)邏輯) 
  7.  *  
  8.  * @author Administrator 
  9.  *  
  10.  */  
  11. public class CountImpl implements Count {  
  12.   
  13.     @Override  
  14.     public void queryCount() {  
  15.         System.out.println("查看賬戶方法...");  
  16.   
  17.     }  
  18.   
  19.     @Override  
  20.     public void updateCount() {  
  21.         System.out.println("修改賬戶方法...");  
  22.   
  23.     }  
  24.   
  25. }  
  26.   
  27. 、CountProxy.java  
  28. package net.battier.dao.impl;  
  29.   
  30. import net.battier.dao.Count;  
  31.   
  32. /** 
  33.  * 這是一個(gè)代理類(增強(qiáng)CountImpl實(shí)現(xiàn)類) 
  34.  *  
  35.  * @author Administrator 
  36.  *  
  37.  */  
  38. public class CountProxy implements Count {  
  39.     private CountImpl countImpl;  
  40.   
  41.     /** 
  42.      * 覆蓋默認(rèn)構(gòu)造器 
  43.      *  
  44.      * @param countImpl 
  45.      */  
  46.     public CountProxy(CountImpl countImpl) {  
  47.         this.countImpl = countImpl;  
  48.     }  
  49.   
  50.     @Override  
  51.     public void queryCount() {  
  52.         System.out.println("事務(wù)處理之前");  
  53.         // 調(diào)用委托類的方法;  
  54.         countImpl.queryCount();  
  55.         System.out.println("事務(wù)處理之后");  
  56.     }  
  57.   
  58.     @Override  
  59.     public void updateCount() {  
  60.         System.out.println("事務(wù)處理之前");  
  61.         // 調(diào)用委托類的方法;  
  62.         countImpl.updateCount();  
  63.         System.out.println("事務(wù)處理之后");  
  64.   
  65.     }  
  66.   
  67. }  

 

3、TestCount.java 

Java代碼 
  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.impl.CountImpl;  
  4. import net.battier.dao.impl.CountProxy;  
  5.   
  6. /** 
  7.  *測試Count類 
  8.  *  
  9.  * @author Administrator 
  10.  *  
  11.  */  
  12. public class TestCount {  
  13.     public static void main(String[] args) {  
  14.         CountImpl countImpl = new CountImpl();  
  15.         CountProxy countProxy = new CountProxy(countImpl);  
  16.         countProxy.updateCount();  
  17.         countProxy.queryCount();  
  18.   
  19.     }  
  20. }  

 

觀察代碼可以發(fā)現(xiàn)每一個(gè)代理類只能為一個(gè)接口服務(wù),這樣一來程序開發(fā)中必然會產(chǎn)生過多的代理,而且,所有的代理操作除了調(diào)用的方法不一樣之外,其他 的操作都一樣,則此時(shí)肯定是重復(fù)代碼。解決這一問題最好的做法是可以通過一個(gè)代理類完成全部的代理功能,那么此時(shí)就必須使用動態(tài)代理完成。 
再來看一下動態(tài)代理: 
JDK動態(tài)代理中包含一個(gè)類和一個(gè)接口: 
InvocationHandler接口: 
public interface InvocationHandler { 
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; 

參數(shù)說明: 
Object proxy:指被代理的對象。 
Method method:要調(diào)用的方法 
Object[] args:方法調(diào)用時(shí)所需要的參數(shù) 

可以將InvocationHandler接口的子類想象成一個(gè)代理的最終操作類,替換掉ProxySubject。 

Proxy類: 
Proxy類是專門完成代理的操作類,可以通過此類為一個(gè)或多個(gè)接口動態(tài)地生成實(shí)現(xiàn)類,此類提供了如下的操作方法: 
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, 
InvocationHandler h) 
                               throws IllegalArgumentException 
參數(shù)說明: 
ClassLoader loader:類加載器 
Class<?>[] interfaces:得到全部的接口 
InvocationHandler h:得到InvocationHandler接口的子類實(shí)例 

Ps:類加載器 
在Proxy類中的newProxyInstance()方法中需要一個(gè)ClassLoader類的實(shí)例,ClassLoader實(shí)際上對應(yīng)的是類加載器,在Java中主要有一下三種類加載器; 
Booststrap ClassLoader:此加載器采用C++編寫,一般開發(fā)中是看不到的; 
Extendsion ClassLoader:用來進(jìn)行擴(kuò)展類的加載,一般對應(yīng)的是jre\lib\ext目錄中的類; 
AppClassLoader:(默認(rèn))加載classpath指定的類,是最常使用的是一種加載器。 

動態(tài)代理 
與靜態(tài)代理類對照的是動態(tài)代理類,動態(tài)代理類的字節(jié)碼在程序運(yùn)行時(shí)由Java反射機(jī)制動態(tài)生成,無需程序員手工編寫它的源代碼。 動態(tài)代理類不僅簡化了編程工作,而且提高了軟件系統(tǒng)的可擴(kuò)展性,因?yàn)镴ava 反射機(jī)制可以生成任意類型的動態(tài)代理類。java.lang.reflect 包中的Proxy類和InvocationHandler 接口提供了生成動態(tài)代理類的能力。 

動態(tài)代理示例: 
1、BookFacade.java 

Java代碼 
  1. package net.battier.dao;  
  2.   
  3. public interface BookFacade {  
  4.     public void addBook();  
  5. }  

 

2、BookFacadeImpl.java 

Java代碼 
  1. package net.battier.dao.impl;  
  2.   
  3. import net.battier.dao.BookFacade;  
  4.   
  5. public class BookFacadeImpl implements BookFacade {  
  6.   
  7.     @Override  
  8.     public void addBook() {  
  9.         System.out.println("增加圖書方法。。。");  
  10.     }  
  11.   
  12. }  
  13.   
  14. 、BookFacadeProxy.java  
  15.   
  16. package net.battier.proxy;  
  17.   
  18. import java.lang.reflect.InvocationHandler;  
  19. import java.lang.reflect.Method;  
  20. import java.lang.reflect.Proxy;  
  21.   
  22. /** 
  23.  * JDK動態(tài)代理代理類 
  24.  *  
  25.  * @author student 
  26.  *  
  27.  */  
  28. public class BookFacadeProxy implements InvocationHandler {  
  29.     private Object target;  
  30.     /** 
  31.      * 綁定委托對象并返回一個(gè)代理類 
  32.      * @param target 
  33.      * @return 
  34.      */  
  35.     public Object bind(Object target) {  
  36.         this.target = target;  
  37.         //取得代理對象  
  38.         return Proxy.newProxyInstance(target.getClass().getClassLoader(),  
  39.                 target.getClass().getInterfaces(), this);   //要綁定接口(這是一個(gè)缺陷,cglib彌補(bǔ)了這一缺陷)  
  40.     }  
  41.   
  42.     @Override  
  43.     /** 
  44.      * 調(diào)用方法 
  45.      */  
  46.     public Object invoke(Object proxy, Method method, Object[] args)  
  47.             throws Throwable {  
  48.         Object result=null;  
  49.         System.out.println("事物開始");  
  50.         //執(zhí)行方法  
  51.         result=method.invoke(target, args);  
  52.         System.out.println("事物結(jié)束");  
  53.         return result;  
  54.     }  
  55.   
  56. }  

 

3、TestProxy.java 

Java代碼 
  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.BookFacade;  
  4. import net.battier.dao.impl.BookFacadeImpl;  
  5. import net.battier.proxy.BookFacadeProxy;  
  6.   
  7. public class TestProxy {  
  8.   
  9.     public static void main(String[] args) {  
  10.         BookFacadeProxy proxy = new BookFacadeProxy();  
  11.         BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());  
  12.         bookProxy.addBook();  
  13.     }  
  14.   
  15. }  

 

但是,JDK的動態(tài)代理依靠接口實(shí)現(xiàn),如果有些類并沒有實(shí)現(xiàn)接口,則不能使用JDK代理,這就要使用cglib動態(tài)代理了。 

Cglib動態(tài)代理 
JDK的動態(tài)代理機(jī)制只能代理實(shí)現(xiàn)了接口的類,而不能實(shí)現(xiàn)接口的類就不能實(shí)現(xiàn)JDK的動態(tài)代理,cglib是針對類來實(shí)現(xiàn)代理的,他的原理是對指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對final修飾的類進(jìn)行代理。 
示例 
1、BookFacadeCglib.java 

Java代碼 
  1. package net.battier.dao;  
  2.   
  3. public interface BookFacade {  
  4.     public void addBook();  
  5. }  

 

2、BookCadeImpl1.java 

Java代碼 
  1. package net.battier.dao.impl;  
  2.   
  3. /** 
  4.  * 這個(gè)是沒有實(shí)現(xiàn)接口的實(shí)現(xiàn)類 
  5.  *  
  6.  * @author student 
  7.  *  
  8.  */  
  9. public class BookFacadeImpl1 {  
  10.     public void addBook() {  
  11.         System.out.println("增加圖書的普通方法...");  
  12.     }  
  13. }  


3、BookFacadeProxy.java 

Java代碼 
  1. package net.battier.proxy;  
  2.   
  3. import java.lang.reflect.Method;  
  4.   
  5. import net.sf.cglib.proxy.Enhancer;  
  6. import net.sf.cglib.proxy.MethodInterceptor;  
  7. import net.sf.cglib.proxy.MethodProxy;  
  8.   
  9. /** 
  10.  * 使用cglib動態(tài)代理 
  11.  *  
  12.  * @author student 
  13.  *  
  14.  */  
  15. public class BookFacadeCglib implements MethodInterceptor {  
  16.     private Object target;  
  17.   
  18.     /** 
  19.      * 創(chuàng)建代理對象 
  20.      *  
  21.      * @param target 
  22.      * @return 
  23.      */  
  24.     public Object getInstance(Object target) {  
  25.         this.target = target;  
  26.         Enhancer enhancer = new Enhancer();  
  27.         enhancer.setSuperclass(this.target.getClass());  
  28.         // 回調(diào)方法  
  29.         enhancer.setCallback(this);  
  30.         // 創(chuàng)建代理對象  
  31.         return enhancer.create();  
  32.     }  
  33.   
  34.     @Override  
  35.     // 回調(diào)方法  
  36.     public Object intercept(Object obj, Method method, Object[] args,  
  37.             MethodProxy proxy) throws Throwable {  
  38.         System.out.println("事物開始");  
  39.         proxy.invokeSuper(obj, args);  
  40.         System.out.println("事物結(jié)束");  
  41.         return null;  
  42.   
  43.   
  44.     }  
  45.   
  46. }  


4、TestCglib.java 

Java代碼 
  1. package net.battier.test;  
  2.   
  3. import net.battier.dao.impl.BookFacadeImpl1;  
  4. import net.battier.proxy.BookFacadeCglib;  
  5.   
  6. public class TestCglib {  
  7.       
  8.     public static void main(String[] args) {  
  9.         BookFacadeCglib cglib=new BookFacadeCglib();  
  10.         BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  
  11.         bookCglib.addBook();  
  12.     }  

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩夫妻午夜性生活视频| 日韩欧美精品一区二区三区| 冬爱琴音一区二区中文字幕| 国产精品内射视频免费| 91人妻人人澡人人人人精品| 中文字幕日产乱码一区二区| 初尝人妻少妇中文字幕在线| 国产老熟女超碰一区二区三区| 亚洲中文字幕在线视频频道| 精品欧美国产一二三区| 日韩一区欧美二区国产| 日韩人妻少妇一区二区| 国产精品成人一区二区在线| 日韩av亚洲一区二区三区| 国产精品午夜性色视频| 亚洲一区在线观看蜜桃| 欧美国产日韩变态另类在线看| 国产亚洲精品久久久优势| 国产亚洲视频香蕉一区| 国产精品一区二区三区欧美| 欧美区一区二在线播放| 欧美亚洲综合另类色妞| 天海翼精品久久中文字幕| 国产精品欧美一区二区三区| 女人精品内射国产99| 国产又粗又长又爽又猛的视频| 国产一级一片内射视频在线| 国产精品99一区二区三区| 夫妻性生活黄色录像视频| 日韩欧美国产三级在线观看| 国产日韩综合一区在线观看| 国产精品夜色一区二区三区不卡| 人妻乱近亲奸中文字幕| 亚洲一区二区三区有码| 欧美日韩精品一区免费| 老司机精品视频在线免费| 国产黑人一区二区三区| 免费黄片视频美女一区| 亚洲中文字幕有码在线观看| 亚洲精品福利视频在线观看| 欧美精品中文字幕亚洲|