日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

如何解决代理模式详解的原理详解

發布時間:2023/12/20 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何解决代理模式详解的原理详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?我特意將本系列改了下名字,原名是《設計模式學習之路》,原因是因為之前寫過一篇《spring源碼學習之路》,但是我感覺本次寫二十三種設計模式,更多的還是分享給各位自己的理解,所以感覺學習之路有點不合適,另外,從本章開始,正式啟用本人稱呼,LZ。

? ? ? ? ? ? ? ?好了,廢話至此,本章接著討論第二種要介紹的設計模式,代理模式。

? ? ? ? ? ? ? ?LZ不希望寫的東西與網絡上的資料千篇一律,所以這一系列不會像很多典型文章一章,只是列出這個模式的定義以及一堆適用的情況,然后就是一堆這個模式的各個角色,對于這種羅列LZ并不反對,相比之下會比較清晰,但是如果脫離了實際,就會導致看的人特別是初學者覺得設計模式很陌生很遙遠。

? ? ? ? ? ? ? ?LZ并不反對這種教學式的標準模式,但說實話,LZ本人看這種帖子從來都感覺收獲不大,看一遍看一遍,到現在都沒記住那些各個適用的情況與一堆亂七八糟的角色。

? ? ? ? ? ? ? ?所以LZ探討代理模式,不會再按這個步驟進行,而是跟著自己的思維進行。

? ? ? ? ? ? ? ?首先代理模式,可以分為兩種,一種是靜態代理,一種是動態代理。

? ? ? ? ? ? ? ?兩種代理從虛擬機加載類的角度來講,本質上都是一樣的,都是在原有類的行為基礎上,加入一些多出的行為,甚至完全替換原有的行為。

? ? ? ? ? ? ? ?靜態代理采用的方式就是我們手動的將這些行為換進去,然后讓編譯器幫我們編譯,同時也就將字節碼在原有類的基礎上加入一些其他的東西或者替換原有的東西,產生一個新的與原有類接口相同卻行為不同的類型。

? ? ? ? ? ? ? ?說歸說,我們來真實的去試驗一下,實驗的話需要找一個示例,就拿我們的數據庫連接來做例子吧。

? ? ? ? ? ? ? ?我們都知道,數據庫連接是很珍貴的資源,頻繁的開關數據庫連接是非常浪費服務器的CPU資源以及內存的,所以我們一般都是使用數據庫連接池來解決這一問題,即創造一堆等待被使用的連接,等到用的時候就從池里取一個,不用了再放回去,數據庫連接在整個應用啟動期間,幾乎是不關閉的,除非是超過了最大閑置時間。

? ? ? ? ? ? ? ?但是在程序員編寫程序的時候,會經常使用connection.close()這樣的方法,去關閉數據庫連接,而且這樣做是對的,所以你并不能告訴程序員們說,你們使用連接都不要關了,去調用一個其他的類似歸還給連接池的方法吧。這是不符合程序員的編程思維的,也很勉強,而且具有風險性,因為程序員會忘的。

? ? ? ? ? ? ? ?解決這一問題的辦法就是使用代理模式,因為代理模式可以替代原有類的行為,所以我們要做的就是替換掉connection的close行為。

? ? ? ? ? ? ? ?下面是connection接口原有的樣子,我去掉了很多方法,因為都類似,全貼上來占地方。

[java]?view plain?copy
  • import?java.sql.SQLException;??
  • import?java.sql.Statement;??
  • import?java.sql.Wrapper;??
  • ??
  • public?interface?Connection??extends?Wrapper?{??
  • ??????
  • ????Statement?createStatement()?throws?SQLException;??
  • ??????
  • ????void?close()?throws?SQLException;??
  • ??????
  • }??
  • ? ? ? ? ? ? ? 這里只貼了兩個方法,但是我們代理的精髓只要兩個方法就能掌握,下面使用靜態代理,采用靜態代理我們通常會使用組合的方式,為了保持對程序猿是透明的,我們實現Connection這個接口。

    ????????????? 如下所示。

    [java]?view plain?copy
  • import?java.sql.SQLException;??
  • import?java.sql.Statement;??
  • ??
  • ??
  • public?class?ConnectionProxy?implements?Connection{??
  • ??????
  • ????private?Connection?connection;??
  • ??????
  • ????public?ConnectionProxy(Connection?connection)?{??
  • ????????super();??
  • ????????this.connection?=?connection;??
  • ????}??
  • ??
  • ????public?Statement?createStatement()?throws?SQLException{??
  • ????????return?connection.createStatement();??
  • ????}??
  • ??????
  • ????public?void?close()?throws?SQLException{??
  • ????????System.out.println("不真正關閉連接,歸還給連接池");??
  • ????}??
  • ??
  • }??
  • ? ? ? ? ? ? ? ? 我們在構造方法中讓調用者強行傳入一個原有的連接,接下來我們將我們不關心的方法,交給真正的Connection接口去處理,就像createStatement方法一樣,而我們將真正關心的close方法用我們自己希望的方式去進行。

    ? ? ? ? ? ? ? ? 此處為了更形象,LZ給出一個本人寫的非常簡單的連接池,意圖在于表明實現的思路。下面我們來看一下連接池的變化,在里面注明了變化點。

    [java]?view plain?copy
  • import?java.sql.Connection;??
  • import?java.sql.DriverManager;??
  • import?java.sql.SQLException;??
  • import?java.util.LinkedList;??
  • ??
  • public?class?DataSource?{??
  • ??????
  • ????private?static?LinkedList<Connection>?connectionList?=?new?LinkedList<Connection>();??
  • ??????
  • ????static{??
  • ????????try?{??
  • ????????????Class.forName("com.mysql.jdbc.Driver");??
  • ????????}?catch?(ClassNotFoundException?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ????}??
  • ??????
  • ????private?static?Connection?createNewConnection()?throws?SQLException{??
  • ????????return?DriverManager.getConnection("url","username",?"password");??
  • ????}??
  • ??????
  • ????private?DataSource(){??
  • ????????if?(connectionList?==?null?||?connectionList.size()?==?0)?{??
  • ????????????for?(int?i?=?0;?i?<?10;?i++)?{??
  • ????????????????try?{??
  • ????????????????????connectionList.add(createNewConnection());??
  • ????????????????}?catch?(SQLException?e)?{??
  • ????????????????????e.printStackTrace();??
  • ????????????????}??
  • ????????????}??
  • ????????}??
  • ????}??
  • ??????
  • ????public?Connection?getConnection()?throws?Exception{??
  • ????????if?(connectionList.size()?>?0)?{??
  • ????????????//return?connectionList.remove();??這是原有的方式,直接返回連接,這樣可能會被程序員把連接給關閉掉??
  • ????????????//下面是使用代理的方式,程序員再調用close時,就會歸還到連接池??
  • ????????????return?new?ConnectionProxy(connectionList.remove());??
  • ????????}??
  • ????????return?null;??
  • ????}??
  • ??????
  • ????public?void?recoveryConnection(Connection?connection){??
  • ????????connectionList.add(connection);??
  • ????}??
  • ??????
  • ????public?static?DataSource?getInstance(){??
  • ????????return?DataSourceInstance.dataSource;??
  • ????}??
  • ??????
  • ????private?static?class?DataSourceInstance{??
  • ??????????
  • ????????private?static?DataSource?dataSource?=?new?DataSource();??
  • ??????????
  • ????}??
  • ??????
  • }??
  • ? ? ? ? ? ? ? ? 連接池我們把它做成單例,所以假設是上述連接池的話,我們代理中的close方法可以再具體化一點,就像下面這樣,用歸還給連接池的動作取代關閉連接的動作。

    [java]?view plain?copy
  • public?void?close()?throws?SQLException{??
  • ????DataSource.getInstance().recoveryConnection(connection);??
  • }??
  • ? ? ? ? ? ? ? ? 好了,這下我們的連接池返回的連接全是代理,就算程序員調用了close方法也只會歸還給連接池了。

    ? ? ? ? ? ? ? ??我們使用代理模式解決了上述問題,從靜態代理的使用上來看,我們一般是這么做的。

    ? ? ? ? ? ? ? ? 1,代理類一般要持有一個被代理的對象的引用。

    ? ? ? ? ? ? ? ? 2,對于我們不關心的方法,全部委托給被代理的對象處理。

    ? ? ? ? ? ? ? ? 3,自己處理我們關心的方法。

    ? ? ? ? ? ? ? ? 這種代理是死的,不會在運行時動態創建,因為我們相當于在編譯期,也就是你按下CTRL+S的那一刻,就給被代理的對象生成了一個不可動態改變的代理類。

    ? ? ? ? ? ? ? ?靜態代理對于這種,被代理的對象很固定,我們只需要去代理一個類或者若干固定的類,數量不是太多的時候,可以使用,而且其實效果比動態代理更好,因為動態代理就是在運行期間動態生成代理類,所以需要消耗的時間會更久一點。就像上述的情況,其實就比較適合使用靜態代理。

    ? ? ? ? ? ? ? ?下面介紹下動態代理,動態代理是JDK自帶的功能,它需要你去實現一個InvocationHandler接口,并且調用Proxy的靜態方法去產生代理類。

    ? ? ? ? ? ? ? ?接下來我們依然使用上面的示例,但是這次該用動態代理處理,我們來試一下看如何做。

    [java]?view plain?copy
  • import?java.lang.reflect.InvocationHandler;??
  • import?java.lang.reflect.Method;??
  • import?java.lang.reflect.Proxy;??
  • import?java.sql.Connection;??
  • ??
  • ??
  • public?class?ConnectionProxy?implements?InvocationHandler{??
  • ??????
  • ????private?Connection?connection;??
  • ??????
  • ????public?ConnectionProxy(Connection?connection)?{??
  • ????????super();??
  • ????????this.connection?=?connection;??
  • ????}??
  • ??
  • ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{??
  • ????????//這里判斷是Connection接口的close方法的話??
  • ????????if?(Connection.class.isAssignableFrom(proxy.getClass())?&&?method.getName().equals("close"))?{??
  • ????????????//我們不執行真正的close方法??
  • ????????????//method.invoke(connection,?args);??
  • ????????????//將連接歸還連接池??
  • ????????????DataSource.getInstance().recoveryConnection(connection);??
  • ????????????return?null;??
  • ????????}else?{??
  • ????????????return?method.invoke(connection,?args);??
  • ????????}??
  • ????}??
  • ??????
  • ????public?Connection?getConnectionProxy(){??
  • ????????return?(Connection)?Proxy.newProxyInstance(getClass().getClassLoader(),?new?Class[]{Connection.class},?this);??
  • ????}??
  • ??????
  • }??
  • ? ? ? ? ? ? ? ?上面是我們針對connection寫的動態代理,InvocationHandler接口只有一個invoke方法需要實現,這個方法是用來在生成的代理類用回調使用的,關于動態代理的原理一會做詳細的分析,這里我們先只關注用法。很顯然,動態代理是將每個方法的具體執行過程交給了我們在invoke方法里處理。而具體的使用方法,我們只需要創造一個ConnectionProxy的實例,并且將調用getConnectionProxy方法的返回結果作為數據庫連接池返回的連接就可以了。

    ? ? ? ? ? ? ? ?上述便是我們針對connection做動態代理的方式,但是我們從中得不到任何好處,除了能少寫點代碼以外,因為這個動態代理還是只能代理Connection這一個接口,如果我們寫出這種動態代理的方式的話,說明我們應該使用靜態代理處理這個問題,因為它代表我們其實只希望代理一個類就好。從重構的角度來說,其實更簡單點,那就是在你發現你使用靜態代理的時候,需要寫一大堆重復代碼的時候,就請改用動態代理試試吧。

    ? ? ? ? ? ? ? ?通常情況下,動態代理的使用是為了解決這樣一種問題,就是我們需要代理一系列類的某一些方法,最典型的應用就是我們前段時間討論過的springAOP,我們需要創造出一批代理類,切入到一系列類當中的某一些方法中。下面給出一個經常使用的動態代理方式。

    [java]?view plain?copy
  • import?java.lang.reflect.InvocationHandler;??
  • import?java.lang.reflect.Method;??
  • import?java.lang.reflect.Proxy;??
  • ??
  • ??
  • public?class?DynamicProxy?implements?InvocationHandler{??
  • ??????
  • ????private?Object?source;??
  • ??????
  • ????public?DynamicProxy(Object?source)?{??
  • ????????super();??
  • ????????this.source?=?source;??
  • ????}??
  • ??????
  • ????public?void?before(){??
  • ????????System.out.println("在方法前做一些事,比如打開事務");??
  • ????}??
  • ??????
  • ????public?void?after(){??
  • ????????System.out.println("在方法返回前做一些事,比如提交事務");??
  • ????}??
  • ??
  • ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{??
  • ????????//假設我們切入toString方法,其他其實也是類似的,一般我們這里大部分是針對特定的方法做事情的,通常不會對類的全部方法切入??
  • ????????//比如我們常用的事務管理器,我們通常配置的就是對save,update,delete等方法才打開事務??
  • ????????if?(method.getName().equals("toString"))?{??
  • ????????????before();??
  • ????????}??
  • ????????Object?result?=?method.invoke(source,?args);??
  • ????????if?(method.getName().equals("toString"))?{??
  • ????????????after();??
  • ????????}??
  • ????????return?result;??
  • ????}??
  • ??????
  • ????public?Object?getProxy(){??
  • ????????return?Proxy.newProxyInstance(getClass().getClassLoader(),?source.getClass().getInterfaces(),?this);??
  • ????}??
  • ??????
  • ??????
  • }??
  • ? ? ? ? ? ? ? ? 上述我做了一些注釋,其實已經說明一些問題,這個代理類的作用是可以代理任何類,因為它被傳入的對象是Object,而不再是具體的類,比如剛才的Connection,這些產生的代理類在調用toString方法時會被插入before方法和after方法。

    ? ? ? ? ? ? ? ??動態代理有一個強制性要求,就是被代理的類必須實現了某一個接口,或者本身就是接口,就像我們的Connection。

    ? ? ? ? ? ? ? ? 道理其實很簡單,這是因為動態代理生成的代理類是繼承Proxy類的,并且會實現被你傳入newProxyInstance方法的所有接口,所以我們可以將生成的代理強轉為任意一個代理的接口或者Proxy去使用,但是Proxy里面幾乎全是靜態方法,沒有實例方法,所以轉換成Proxy意義不大,幾乎沒什么用。假設我們的類沒有實現任何接口,那么就意味著你只能將生成的代理類轉換成Proxy,那么就算生成了,其實也沒什么用,而且就算你傳入了接口,可以強轉,你也用不了這個沒有實現你傳入接口的這個類的方法。

    ? ? ? ? ? ? ? ?你可能會說,假設有個接口A,那我將接口A傳給newProxyInstance方法,并代理一個沒實現接口A的類B,但類B與接口A有一樣的方法可以嗎?

    ? ? ? ? ? ? ? ?答案是可以的,并且JDK的動態代理只認你傳入的接口,只要你傳入,你就可以強轉成這個接口,這個一會解釋,但是你無法在invoke方法里調用method.invoke方法,也就是說,你只能全部替換A接口的方法,而不能使用類B中原有與接口A方法描述相同的方法,這是因為invoke中傳入的Method的class信息是接口A,而類B因為沒實現接口A,所以無法執行傳入的Method,會拋出非法參數異常。

    ? ? ? ? ? ? ? ?下面我貼出測試代碼,各位可以自己試一下,具體為何會這樣是在后面解釋的,這里不再多做解釋。

    ? ? ? ? ? ? ? 先是一個普通接口。

    [java]?view plain?copy
  • public?interface?TestInterface?{??
  • ??
  • ????void?method1();??
  • ??????
  • ????void?method2();??
  • ??????
  • ????void?method3();??
  • }??
  • ? ? ? ? ? ? 然后是一個類,和接口一模一樣的方法,但是就是沒實現這個接口。

    [java]?view plain?copy
  • public?class?TestClass{??
  • ??
  • ????public?void?method1()?{??
  • ????????System.out.println("TestClass.method1");??
  • ????}??
  • ??
  • ????public?void?method2()?{??
  • ????????System.out.println("TestClass.method2");??
  • ????}??
  • ??
  • ????public?void?method3()?{??
  • ????????System.out.println("TestClass.method3");??
  • ????}??
  • ??
  • }??
  • ? ? ? ? ? ? ? ?下面是測試類。

    [java]?view plain?copy
  • import?java.lang.reflect.InvocationHandler;??
  • import?java.lang.reflect.Method;??
  • import?java.lang.reflect.Proxy;??
  • ??
  • ??
  • public?class?DynamicProxy?implements?InvocationHandler{??
  • ??????
  • ????private?Object?source;??
  • ??????
  • ????public?DynamicProxy(Object?source)?{??
  • ????????super();??
  • ????????this.source?=?source;??
  • ????}??
  • ??
  • ????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{??
  • ????????System.out.println("接口的方法全部變成這樣了");??
  • ????????//這里source是TestClass,但是我們不能使用反射調用它的方法,像下面這樣,放開這一行會拋異常??
  • ????????//return?method.invoke(source,?args);??
  • ????????return?null;??
  • ????}??
  • ??????
  • ????public?static?void?main(String[]?args)?{??
  • ????????//只要你傳入就可以強轉成功??
  • ????????TestInterface?object?=??(TestInterface)?Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),?new?Class[]{TestInterface.class},?new?DynamicProxy(new?TestClass()));??
  • ????????object.method1();??
  • ????????object.method2();??
  • ????????object.method3();??
  • ????}??
  • }??
  • ? ? ? ? ? ? ? ?上面我們運行就會發現接口的方法全部都只能輸出一個很2的字符串了。如果是要繼續使用TestClass的方法也不是不行,只要你確認你傳入的類包括了所有你傳入的接口的方法,只是沒實現這些接口而已,那么你可以在invoke中這樣使用。

    [java]?view plain?copy
  • public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{??
  • ????????System.out.println("before");??
  • ????????Method?sourceMethod?=?source.getClass().getDeclaredMethod(method.getName(),?method.getParameterTypes());??
  • ????????sourceMethod.setAccessible(true);??
  • ????????Object?result?=?sourceMethod.invoke(source,?args);??
  • ????????System.out.println("after");??
  • ????????return?result;??
  • ????}??
  • ? ? ? ? ? ? ? ? 這就與你實現接口的表現行為一致了,但是我們本來就只需要一句method.invoke就可以了,就因為沒實現接口就要多寫兩行,所以這種突破JDK動態代理必須實現接口的行為就有點畫蛇添足了。因為你本來就實現了該接口的方法,只是差了那一句implements而已。

    ? ? ? ? ? ? ? ?上面寫這個例子只是為了解釋LZ當初的疑惑,因為LZ曾一度認為不實現接口就不能使用動態代理,現在想想那時候LZ有點2,呵呵。

    ? ? ? ? ? ? ? ?好了,從現在開始,我們開始詳細講解動態代理的原理,這算是進階篇,如果是新手的話,可以跳過下面的內容,因為現在還沒必要知道這些,而且弄不好會越看越蒙,不過僅僅是LZ個人建議,你要有耐心,完全可以繼續看下去。

    ? ? ? ? ? ? ? ?接下來我們結合源碼去看一下,代理類是如何產生的,首先當然就是要進入Proxy的newProxyInstance方法,這里是產生代理的入口,源碼如下。

    [java]?view plain?copy
  • ???public?static?Object?newProxyInstance(ClassLoader?loader,??
  • ??????????????????Class<?>[]?interfaces,??
  • ??????????????????InvocationHandler?h)??
  • throws?IllegalArgumentException??
  • ???{??
  • if?(h?==?null)?{??
  • ????throw?new?NullPointerException();??
  • }??
  • ??
  • /*?
  • ?*?Look?up?or?generate?the?designated?proxy?class.?
  • ?*/??
  • Class?cl?=?getProxyClass(loader,?interfaces);??
  • ??
  • /*?
  • ?*?Invoke?its?constructor?with?the?designated?invocation?handler.?
  • ?*/??
  • try?{??
  • ????Constructor?cons?=?cl.getConstructor(constructorParams);??
  • ????return?(Object)?cons.newInstance(new?Object[]?{?h?});??
  • }?catch?(NoSuchMethodException?e)?{??
  • ????throw?new?InternalError(e.toString());??
  • }?catch?(IllegalAccessException?e)?{??
  • ????throw?new?InternalError(e.toString());??
  • }?catch?(InstantiationException?e)?{??
  • ????throw?new?InternalError(e.toString());??
  • }?catch?(InvocationTargetException?e)?{??
  • ????throw?new?InternalError(e.toString());??
  • }??
  • ???}??
  • ? ? ? ? ? ? ? ?這個方法其實很簡單,首先獲取了代理類的運行時Class引用,然后調用了這個Class中的構造方法,這個構造方法只有一個參數,正是InvocationHandler接口,由此產生了一個代理類的實例。那么關鍵的地方就在于如何獲取的代理類運行時的class信息的呢?我們進入getProxyClass方法看一下。為了方便起見,我直接加注釋,這個方法需要解釋的地方比較多。
    (完)
    http://ji63658820.blog.sohu.com/
    http://zhizhi01417.blog.sohu.com/
    http://baquanzhaojiure.blog.sohu.com/
    http://kenchi0072.blog.sohu.com/
    http://zifang439602.blog.sohu.com/
    http://gongpuzhishuozh.blog.sohu.com/
    http://qiaoxun78874.blog.sohu.com/
    http://juyukehuazai.blog.sohu.com/
    http://naoqun271707.blog.sohu.com/
    http://ranghui584859.blog.sohu.com/
    http://kan85274856.blog.sohu.com/
    http://jidou50557525.blog.sohu.com/
    http://yunqun25200989.blog.sohu.com/
    http://pangcao9153130.blog.sohu.com/
    http://koufuyi599899.blog.sohu.com/
    http://sifan76579.blog.sohu.com/
    http://xian40097124.blog.sohu.com/
    http://zhengdi824808.blog.sohu.com/
    http://huiyuan30898.blog.sohu.com/
    http://tuzhi052086.blog.sohu.com/
    http://zigan813704.blog.sohu.com/
    http://aopu127791.blog.sohu.com/
    http://zhixun2111431.blog.sohu.com/
    http://yonglu5882289.blog.sohu.com/
    http://blog.sohu.com/home/news/index.htm
    http://shi05778335.blog.sohu.com/
    http://duntao5889640.blog.sohu.com/
    http://ying56663881.blog.sohu.com/
    http://miyou1chao.blog.sohu.com/
    http://quebeng9112.blog.sohu.com/
    http://langpai3822036.blog.sohu.com/
    http://shangguai483499.blog.sohu.com/
    http://jiaoyi97308.blog.sohu.com/
    http://shazhun795212.blog.sohu.com/
    http://fufang6180765.blog.sohu.com/
    http://xianlekangkao.blog.sohu.com/
    http://duxing0651.blog.sohu.com/
    http://tuohaoba022375.blog.sohu.com/
    http://yuji3gui153382.blog.sohu.com/
    http://zemu1426600.blog.sohu.com/
    http://yacang160402.blog.sohu.com/
    http://gua20742393.blog.sohu.com/
    http://jisuweichun.blog.sohu.com/
    http://pudu6738715.blog.sohu.com/
    http://leitou52561606.blog.sohu.com/
    http://dicisixian.blog.sohu.com/
    http://dituo654174.blog.sohu.com/
    http://tutuo81160508.blog.sohu.com/
    http://guaqiaotushuqin.blog.sohu.com/
    http://tanjiaju772135.blog.sohu.com/
    http://xia22401507.blog.sohu.com/
    http://pojiao2520371.blog.sohu.com/
    http://chicurangou.blog.sohu.com/
    http://luzaweituan.blog.sohu.com/
    http://chengfen860412.blog.sohu.com/
    http://poba73704219.blog.sohu.com/
    http://mei89825164.blog.sohu.com/
    http://duang32836452.blog.sohu.com/
    http://jiubei390139.blog.sohu.com/
    http://xieraoqiefankao.blog.sohu.com/
    http://yilang47832.blog.sohu.com/
    http://sijiao2818166.blog.sohu.com/
    http://lutong084166.blog.sohu.com/
    http://yunbai038826.blog.sohu.com/
    http://chuishao96160.blog.sohu.com/
    http://duanao45202.blog.sohu.com/
    http://zena58309333.blog.sohu.com/
    http://zhaopouga.blog.sohu.com/
    http://jijiziluzi.blog.sohu.com/
    http://youmu86072747.blog.sohu.com/
    http://yiqiao0799346.blog.sohu.com/
    http://fangqiang2gong.blog.sohu.com/
    http://luxuan5003.blog.sohu.com/
    http://lanlue1673873.blog.sohu.com/
    http://wopiao8981.blog.sohu.com/
    http://yiliezhiyun.blog.sohu.com/
    http://zenxunaozhundi.blog.sohu.com/
    http://xionggong001752.blog.sohu.com/
    http://zhichenlintugui.blog.sohu.com/
    http://queyi41528049.blog.sohu.com/
    http://jiejia423144.blog.sohu.com/
    http://shaogangliaoqin.blog.sohu.com/
    http://jiuchun3411223.blog.sohu.com/
    http://jiaoba81253.blog.sohu.com/
    http://fangjiao495408.blog.sohu.com/
    http://fuqiang376.blog.sohu.com/
    http://zouhuiyongtanch.blog.sohu.com/
    http://xiqiao92002.blog.sohu.com/
    http://shu82355473.blog.sohu.com/
    http://ziyuan254736.blog.sohu.com/
    http://sitan4pi158934.blog.sohu.com/
    http://jueyan6xia.blog.sohu.com/
    http://dongliang43145.blog.sohu.com/
    http://yiwei71321060.blog.sohu.com/
    http://cizhuang49210.blog.sohu.com/
    http://fenpan87260.blog.sohu.com/
    http://xiyo0267815.blog.sohu.com/
    http://yingrong5mei.blog.sohu.com/
    http://jingtong2234.blog.sohu.com/
    http://tuikang744040.blog.sohu.com/
    http://depaisiyi.blog.sohu.com/
    http://olu5514216.blog.sohu.com/
    http://gou86478183.blog.sohu.com/
    http://weiyuan1song.blog.sohu.com/
    http://jiaoxia718784.blog.sohu.com/
    http://taoji03753000.blog.sohu.com/
    http://zhunpanxianyunf.blog.sohu.com/
    http://linyediweijiang.blog.sohu.com/
    http://lanyi47493068.blog.sohu.com/
    http://bidui003324.blog.sohu.com/
    http://xunqie35956392.blog.sohu.com/
    http://puyi22288.blog.sohu.com/
    http://jiazhe3155.blog.sohu.com/
    http://gan82261201.blog.sohu.com/
    http://jiazhe3155.blog.sohu.com/
    http://yong06919851.blog.sohu.com/
    http://qinlin934705.blog.sohu.com/
    http://zhangji762369.blog.sohu.com/
    http://xinhan954.blog.sohu.com/
    http://ozhishangba.blog.sohu.com/
    http://shaxin5933667.blog.sohu.com/
    http://jiuyazhijidi.blog.sohu.com/
    http://ji00478205.blog.sohu.com/
    http://daoxian5666001.blog.sohu.com/
    http://duxuan1146.blog.sohu.com/
    http://xiegui137392.blog.sohu.com/
    http://jiuao92856238.blog.sohu.com/
    http://pusong8394.blog.sohu.com/
    http://jidao8227035.blog.sohu.com/
    http://shiqi625077.blog.sohu.com/
    http://chijia501914.blog.sohu.com/
    http://zhongshi537706.blog.sohu.com/
    http://zhanglu4738465.blog.sohu.com/
    http://shuojia670.blog.sohu.com/
    http://ke63240682.blog.sohu.com/
    http://rangyongziliang.blog.sohu.com/
    http://xunshan7916.blog.sohu.com/
    http://nacong632878.blog.sohu.com/
    http://dumeihailazhuan.blog.sohu.com/
    http://langao48260378.blog.sohu.com/
    http://tulan64540.blog.sohu.com/
    http://qinqiang5si.blog.sohu.com/
    http://langren750634.blog.sohu.com/
    http://tuoshou730823.blog.sohu.com/
    http://beixian305396.blog.sohu.com/
    http://koutuomeijingtu.blog.sohu.com/
    http://kehui0240677.blog.sohu.com/
    http://han36991002.blog.sohu.com/
    http://huituo863.blog.sohu.com/
    http://youqun0rang.blog.sohu.com/
    http://pujiu3104779.blog.sohu.com/
    http://jiuba0958174.blog.sohu.com/
    http://fugu1860309345.blog.sohu.com/
    http://bazhi047569.blog.sohu.com/
    http://wogan4515.blog.sohu.com/
    http://chuncheng1chao.blog.sohu.com/
    http://qingcheng367532.blog.sohu.com/
    http://linshanyeanhan.blog.sohu.com/
    http://jushi7pa051073.blog.sohu.com/
    http://za67896020.blog.sohu.com/
    http://jiehui5chi.blog.sohu.com/
    http://yongtuo61728.blog.sohu.com/
    http://daofu64180926.blog.sohu.com/
    http://jizhuo0huan.blog.sohu.com/
    http://ziren3128194.blog.sohu.com/
    http://fuqiangrangxia.blog.sohu.com/
    http://yunbu5jue.blog.sohu.com/
    http://hejiao9593454.blog.sohu.com/
    http://poyeduhai.blog.sohu.com/
    http://zhan37581019.blog.sohu.com/
    http://laotan164675.blog.sohu.com/
    http://xieqinkaoche.blog.sohu.com/
    http://liaorao0254.blog.sohu.com/
    http://koucong9mei.blog.sohu.com/
    http://pamu6355864.blog.sohu.com/
    http://jiaotuo350363.blog.sohu.com/
    http://bachun6523.blog.sohu.com/
    http://sike461935.blog.sohu.com/
    http://latuan317871.blog.sohu.com/

    http://konglan6560643.blog.sohu.com/




































    [ja

    總結

    以上是生活随笔為你收集整理的如何解决代理模式详解的原理详解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。