<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                什么是代理模式? ![](https://img.kancloud.cn/9c/3b/9c3b31a1bd3f86c57d0e4b9a8c15276d_590x195.png) 代理模式的定義:代理模式給某一個對象提供一個代理對象,并由代理對象控制對原對象的引用。通俗的來講代理模式就是我們生活中常見的中介。 為什么要用代理模式? * 中介隔離作用:在某些情況下,一個客戶類不想或者不能直接引用一個委托對象,而代理類對象可以在客戶類和委托對象之間起到中介的作用,其特征是代理類和委托類實現相同的接口。 * 開閉原則,增加功能:代理類除了是客戶類和委托類的中介之外,我們還可以通過給代理類增加額外的功能來擴展委托類的功能,這樣做我們只需要修改代理類而不需要再修改委托類,符合代碼設計的開閉原則。代理類主要負責為委托類預處理消息、過濾消息、把消息轉發給委托類,以及事后對返回結果的處理等。代理類本身并不真正實現服務,而是同過調用委托類的相關方法,來提供特定的服務。真正的業務功能還是由委托類來實現,但是可以在業務功能執行的前后加入一些公共的服務。例如我們想給項目加入緩存、日志這些功能,我們就可以使用代理類來完成,而沒必要打開已經封裝好的委托類。 有哪幾種代理模式? ? ? ? ?我們有多種不同的方式來實現代理。如果按照代理創建的時期來進行分類的話, 可以分為兩種:靜態代理、動態代理。靜態代理是由程序員創建或特定工具自動生成源代碼,在對其編譯。在程序員運行之前,代理類.class文件就已經被創建了。動態代理是在程序運行時通過反射機制動態創建的。 1.靜態代理? ? ? 第一步:創建服務類接口 ~~~ package main.java.proxy; /** * @Auther: dan gao * @Description: * @Date: 22:40 2018/1/9 0009 */ public interface BuyHouse { void buyHosue(); } ~~~ 第二步:實現服務接口 ~~~ import main.java.proxy.BuyHouse; public class BuyHouseImpl implements BuyHouse { @Override public void buyHosue() { System.out.println("我要買房"); } } ~~~ 第三步:創建代理類 ~~~ package main.java.proxy.impl; import main.java.proxy.BuyHouse; public class BuyHouseProxy implements BuyHouse { private BuyHouse buyHouse; public BuyHouseProxy(final BuyHouse buyHouse) { this.buyHouse = buyHouse; } @Override public void buyHosue() { System.out.println("買房前準備"); buyHouse.buyHosue(); System.out.println("買房后裝修"); } } ~~~ 第四步:編寫測試類 ~~~ import main.java.proxy.impl.BuyHouseImpl; import main.java.proxy.impl.BuyHouseProxy; public class ProxyTest { public static void main(String\[\]args) { BuyHouse buyHouse = new BuyHouseImpl(); buyHouse.buyHosue(); BuyHouseProxy buyHouseProxy = new BuyHouseProxy(buyHouse); buyHouseProxy.buyHosue(); } } ~~~ 靜態代理總結: 優點:可以做到在符合開閉原則的情況下對目標對象進行功能擴展。 缺點:我們得為每一個服務都得創建代理類,工作量太大,不易管理。同時接口一旦發生改變,代理類也得相應修改。 2.動態代理 在動態代理中我們不再需要再手動的創建代理類,我們只需要編寫一個動態處理器就可以了。真正的代理對象由JDK再運行時為我們動態的來創建。 第一步:編寫動態處理器 ~~~ package main.java.proxy.impl; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyHandler implements InvocationHandler { private Object object; public DynamicProxyHandler(final Object object) { this.object = object; } @Override public Object invoke(Object proxy, Method method, Object\[\]args) throws Throwable { System.out.println("買房前準備"); Object result = method.invoke(object, args); System.out.println("買房后裝修"); return result; } } ~~~ 第二步:編寫測試類 ~~~ package main.java.proxy.test; import main.java.proxy.BuyHouse; import main.java.proxy.impl.BuyHouseImpl; import main.java.proxy.impl.DynamicProxyHandler; import java.lang.reflect.Proxy; public class DynamicProxyTest { public static void main(String\[\]args) { BuyHouse buyHouse = new BuyHouseImpl(); BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), new Class\[\]{ BuyHouse.class },new DynamicProxyHandler(buyHouse)); proxyBuyHouse.buyHosue(); } } ~~~ 注意Proxy.newProxyInstance()方法接受三個參數: * ClassLoader loader:指定當前目標對象使用的類加載器,獲取加載器的方法是固定的 * Class\[\] interfaces:指定目標對象實現的接口的類型,使用泛型方式確認類型 * InvocationHandler:指定動態處理器,執行目標對象的方法時,會觸發事件處理器的方法 動態代理總結:雖然相對于靜態代理,動態代理大大減少了我們的開發任務,同時減少了對業務接口的依賴,降低了耦合度。但是還是有一點點小小的遺憾之處,那就是它始終無法擺脫僅支持interface代理的桎梏,因為它的設計注定了這個遺憾。回想一下那些動態生成的代理類的繼承關系圖,它們已經注定有一個共同的父類叫Proxy。Java的繼承機制注定了這些動態代理類們無法實現對class的動態代理,原因是多繼承在Java中本質上就行不通。有很多條理由,人們可以否定對 class代理的必要性,但是同樣有一些理由,相信支持class動態代理會更美好。接口和類的劃分,本就不是很明顯,只是到了Java中才變得如此的細化。如果只從方法的聲明及是否被定義來考量,有一種兩者的混合體,它的名字叫抽象類。實現對抽象類的動態代理,相信也有其內在的價值。此外,還有一些歷史遺留的類,它們將因為沒有實現任何接口而從此與動態代理永世無緣。如此種種,不得不說是一個小小的遺憾。但是,不完美并不等于不偉大,偉大是一種本質,Java動態代理就是佐例。 3.CGLIB代理 ? ? ? ?JDK實現動態代理需要實現類通過接口定義業務方法,對于沒有接口的類,如何實現動態代理呢,這就需要CGLib了。CGLib采用了非常底層的字節碼技術,其原理是通過字節碼技術為一個類創建子類,并在子類中采用方法攔截的技術攔截所有父類方法的調用,順勢織入橫切邏輯。但因為采用的是繼承,所以不能對final修飾的類進行代理。JDK動態代理與CGLib動態代理均是實現Spring AOP的基礎。 第一步:創建CGLIB代理類 ~~~ package dan.proxy.impl; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class CglibProxy implements MethodInterceptor { private Object target; public Object getInstance(final Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object object, Method method, Object\[\]args, MethodProxy methodProxy) throws Throwable { System.out.println("買房前準備"); Object result = methodProxy.invoke(object, args); System.out.println("買房后裝修"); return result; } } ~~~ 第二步:創建測試類 ~~~ package dan.proxy.test; import dan.proxy.BuyHouse; import dan.proxy.impl.BuyHouseImpl; import dan.proxy.impl.CglibProxy; public class CglibProxyTest { public static void main(String\[\]args) { BuyHouse buyHouse = new BuyHouseImpl(); CglibProxy cglibProxy = new CglibProxy(); BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse); buyHouseCglibProxy.buyHosue(); } } ~~~ CGLIB代理總結:?CGLIB創建的動態代理對象比JDK創建的動態代理對象的性能更高,但是CGLIB創建代理對象時所花費的時間卻比JDK多得多。所以對于單例的對象,因為無需頻繁創建對象,用CGLIB合適,反之使用JDK方式要更為合適一些。同時由于CGLib由于是采用動態創建子類的方法,對于final修飾的方法無法進行代理。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看