<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      安卓筆記俠

      專注安卓開發(fā)

      導航

      代理模式分類

      一、代理概念

        代理的兩種模式靜態(tài)代理和動態(tài)代理,這個是怎么區(qū)別的我們談一下,Java中都是通過編譯器生成.class文件,在通過JVM讀取,
      然后加載到內存中,生成對應的需要對象,根據(jù)代理類創(chuàng)建的時間分成靜態(tài)和動態(tài)代理,靜態(tài)的代理就是在程序運行前.class文件就存在,
      我們經常使用的代理模式就是靜態(tài)代理,動態(tài)代理就是程序運行時動態(tài)創(chuàng)建,比如JDK的動態(tài)代理和CGLB代理;

      二、靜態(tài)代理----代理模式

         這里我們使用取款機這個例子來說一下,現(xiàn)在假如說你是招商的銀行卡,你需要在工商取款機取款,這里有個規(guī)定那就是每筆需要收費2元,這個工商取款機就是代理對象,你的目標對象就是取款,我們抽象一個取款的接口WithdrawService,招商取款機上面的實現(xiàn)取款機接口ATM,然后工商取款機ATMProxy實現(xiàn)代理角色;當然這里我簡化很多步驟;

       1 /**
       2  * 抽象的取款接口
       3  */
       4 public interface WithdrawService {
       5     int GetByMoneyWithdraw(int money);
       6 }
       7 
       8 /**
       9  * ATM機實現(xiàn)的接口
      10  */
      11 public class ATM implements WithdrawService{
      12     @Override
      13     public int GetByMoneyWithdraw(int money) {
      14         System.out.print("取款"+money);
      15         return money;
      16     }
      17 }
      18 
      19 /**
      20  * 代理對象
      21  */
      22 public class ATMProxy implements WithdrawService {
      23     private ATM atm;
      24     public ATMProxy(ATM atm){
      25         this.atm=atm;
      26     }
      27     @Override
      28     public int GetByMoneyWithdraw(int money) {
      29 
      30         int proxyMoney=2;
      31         System.out.print("取款"+money+":"+"手續(xù)費"+proxyMoney);
      32         atm.GetByMoneyWithdraw(money+proxyMoney);
      33         return money+proxyMoney;
      34     }
      35 }
      36 /**
      37  * 測試類
      38  */
      39 public class ProxyTest {
      40     public static void main(String[] args){
      41         WithdrawService withdrawService=new ATMProxy(new ATM());
      42         withdrawService.GetByMoneyWithdraw(1000);
      43     }
      44 }

      以上就是靜態(tài)代理,在運行前就生成,代理模式的優(yōu)點就在于不直接依賴于目標對象,而是通過代理對象作為中間對象也就是我們經常說的解耦;另外代理對象還可以對實現(xiàn)的方法進行增強,增加自己的規(guī)則,這里我們思考一個問題:當我們每增加一個代理類的時候,我就需要編寫一個類,這樣我們代碼通用很差,另外這樣子會照成系統(tǒng)更加復雜,執(zhí)行速度更加慢;這就背離了我們設計的原則,那么怎么避免這種問題?

      三、動態(tài)代理----JDK動態(tài)代理

         針對于上面提出的問題,通過反射機制,JDK給我們提供Proxy類,這個只是針對于接口的增強,在JVM運行時動態(tài)創(chuàng)建生成。這里簡單說一下JDK通過接口動態(tài)生成代理對象的過程:

          1.獲取WithdrawService接口下所有方法;

          2.生成代理類,默認為命名空間+$+Proxy+類名;

          3.根據(jù)接口,在代碼中動態(tài)創(chuàng)建代理的字節(jié)碼文件;

          4.將字節(jié)碼文件轉化為class文件;

          5.創(chuàng)建InvocationHandler實例handler,來處理代理的方法調用

          6.Proxy的class對象以創(chuàng)建的handler對象為參數(shù),實例一個proxy對象;

         下面我們展示一下JDK實現(xiàn)代理:

       1 /**
       2  * 抽象的取款接口
       3  */
       4 public interface WithdrawService {
       5     int GetByMoneyWithdraw(int money);
       6 }
       7 
       8 /**
       9  * ATM機實現(xiàn)的接口
      10  */
      11 public class ATM implements WithdrawService{
      12     @Override
      13     public int GetByMoneyWithdraw(int money) {
      14         System.out.print("取款"+money);
      15         return money;
      16     }
      17 }
      18 
      19 /**
      20  * JDK動態(tài)代理的實現(xiàn)
      21  */
      22 public class ATMJDKProxy implements InvocationHandler {
      23     //目標對象
      24     private Object target;
      25     //構建目標對象
      26     public ATMJDKProxy(Object target){
      27         super();
      28         this.target=target;
      29     }
      30     //獲取目標的代理對象
      31     public Object getProxy(){
      32         return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),this.target.getClass().getInterfaces(),this);
      33     }
      34     @Override
      35     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      36         System.out.print("執(zhí)行前處理什么事情");
      37         Object result = method.invoke(target, args);
      38         System.out.print("執(zhí)行后處理什么事情");
      39         return result;
      40     }
      41 }
      42 
      43 /**
      44  * 測試類
      45  */
      46 public class ProxyTest {
      47 
      48     public static void main(String[] args) {
      49         WithdrawService withdrawService=new ATM();
      50         ATMJDKProxy atmjdkProxy=new ATMJDKProxy(withdrawService);
      51         WithdrawService proy= (WithdrawService) atmjdkProxy.getProxy();
      52         proy.GetByMoneyWithdraw(1000);
      53     }
      54 }

      四、動態(tài)代理----CGLIB動態(tài)代理 

         JDK動態(tài)代理只能實現(xiàn)對接口方法的增強,不能實現(xiàn)對接口類的的動態(tài)代理。那么我們想動態(tài)生成類的時候怎么辦,不用想了那就是使用CGLIB類庫;這個當然也是在JVM運行時動態(tài)創(chuàng)建,這里也簡單描述下生成ATM動態(tài)代理類的過程:

         1.查找ATM類中的非final的public類型方法;

         2.將這些方法定義轉化為字節(jié)碼;

         3.將組成字節(jié)碼轉化為代理的Clss類;

         4.實現(xiàn)MethodInterceptor 接口,用來處理代理方法上的請求;

         下面我們展示一下CGLIB實現(xiàn)代理:

       1 /**
       2  * ATM不實現(xiàn)接口
       3  */
       4 public class ATM {
       5     public int GetByMoneyWithdraw(int money) {
       6         System.out.print("取款"+money);
       7         return money;
       8     }
       9 }
      10 
      11 /**
      12  * 實現(xiàn)MethodInterceptor
      13  */
      14 public class ATMCGLIBProxy implements MethodInterceptor {
      15     private Object target;
      16     public Object getInstance(Object target){
      17         this.target=target;
      18         Enhancer enhancer=new Enhancer();
      19         enhancer.setSuperclass(this.target.getClass());
      20         enhancer.setCallback(this);
      21         return enhancer.create();
      22     }
      23     @Override
      24     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
      25         System.out.println("開始前");
      26         methodProxy.invokeSuper(o,objects);
      27         System.out.println("開始后");
      28         return null;
      29     }
      30 }
      31 /**
      32  * 測試類
      33  */
      34 public class ProxyTest {
      35 
      36       public static void main(String[] args) {
      37           ATMCGLIBProxy cglib=new ATMCGLIBProxy();
      38           ATM atm = (ATM) cglib.getInstance(new ATM());
      39           atm.GetByMoneyWithdraw(1000);
      40       }
      41 }

      以上是基本實現(xiàn),這里我們簡單說一下CGLIB底層是通過使用字節(jié)碼處理框架ASM,來轉換字節(jié)碼并生成新的類;什么是ASM?ASM是一個Java字節(jié)碼操縱框架,它能被用來動態(tài)生成類或者增強既有類的功能。ASM 可以直接產生二進制 class 文件,也可以在類被加載入 Java 虛擬機之前動態(tài)改變類行為。Java class 被存儲在嚴格格式定義的 .class文件里,這些類文件擁有足夠的元數(shù)據(jù)來解析類中的所有元素:類名稱、方法、屬性以及 Java 字節(jié)碼(指令)。ASM從類文件中讀入信息后,能夠改變類行為,分析類信息,甚至能夠根據(jù)用戶要求生成新類。

         這里需要注意使用這個的時候需要引入:cglib-nodep-2.2.jar;cglib-2.2.jar;asm-3.2jar;

       五、動態(tài)代理----應用場景

        大家執(zhí)行過上面的代碼以后會有一種是曾相識的感覺,在方法執(zhí)行前做一些事,在方法執(zhí)行后做一些事,使我們很容易想到Spring Aop中的通知,這里確實有用到動態(tài)代理,至于別的我暫時還沒有想到,等等那天解讀Spring源碼的時候我們再來探討一下,到此結束;

       

      posted on 2016-10-23 10:30  安卓筆記俠  閱讀(1038)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 乐至县| 九九在线精品国产| 亚洲精品中文字幕无码蜜桃 | 无码国内精品久久人妻蜜桃| 成人av亚洲男人色丁香| 99热这里只有成人精品国产| 国产成人啪精品午夜网站| 成人动漫在线观看| 中文字幕成人精品久久不卡| 欧产日产国产精品精品| 色老头亚洲成人免费影院| 国产精品成人综合色在线| 女同久久一区二区三区| 老太脱裤子让老头玩xxxxx| 亚洲熟妇自偷自拍另欧美| 亚洲男女羞羞无遮挡久久丫| 久久久久久久无码高潮| 日韩有码中文字幕av| 在线免费成人亚洲av| 国产精品天天狠天天看| 国产极品粉嫩尤物一线天| 老司机午夜精品视频资源 | 国产精品不卡一二三区| 日日爽日日操| 一本大道久久a久久综合| 国产99视频精品免费视频36| 久久香蕉国产线看观看猫咪av| 久久一日本道色综合久久| 新化县| 国产99视频精品免费视频76| 久久先锋男人AV资源网站| 新野县| 一面膜上边一面膜下边视频| 日本免费最新高清不卡视频 | 欧美人禽zozo动人物杂交| 成人国产一区二区三区精品| 国产在线观看网址不卡一区| 国产午夜亚洲精品国产成人| 军人粗大的内捧猛烈进出视频 | 国产亚洲精品aaaa片app| 在线一区二区中文字幕|