動態代理

mybatis中用了很多設計模式,其中mappr接口調用使用了動態代理:java

代理模式

    • 代理設計模式

      • 靜態代理
      • 事件通常用接口或者抽象類
      • 代理類(實現這個事件 必須東這個事件才能代理) 包含被代理的事件的主角
      • 事件的主角(也實現這個事件) 被代理的對象
      • 靜態代理 只對一個熟悉 不具有通用性

      • 動態代理
      • 專門作動態代理的接口 implements InvocationHander
        • 重寫invoke方法 什麼均可以
        • 把目標和代理對象捏合成一個新的對象(新的代理類 才能去代理),在捏合的過程當中,把目標的類加載器 接口還有代理對象都傳遞給proxy.newProxyInstance方法
        • getInterfaces() 經過反射得到接口數組
      • jdk下面的Proxy對象下的newInstance,要求必需要有事件,委託人必需要實現事件的接口
      • cglib字節碼修改器
        • 性能更高數組

        • 直接經過類加載器 對類的字節文件進行修改安全

        • 類加載器:將磁盤中的文件經過io流加載到內存中。加載到內存中才能對類進行修改。mybatis

        • 代理通常使用CGLIBProxyapp

        • 不要忘記導入jar包 asm cglib javassist性能

      一個類表明另外一個類,建立現有對象的對象,以便向外界提供功能接口。 向在訪問這個類的時候作一些控制的時候可使用代理模式 增長中間層,實現與被代理類的組合。this

      優勢----爲何時候代理模式spa

      • 職責清晰 高擴展性 智能化設計

      • 當你在訪問一個對象的時侯想要對這個類進行一些控制,(裝飾者模式是加強功能)

      • 提供了對目標對象另外的訪問方式。經過代理對象來訪問目標對象,好處:能夠在目標對象的基礎上增長額外的功能來擴展目標對象的功能。

      • 當你想要對要使用的對象進行修改的時候,不要直接在源碼上進行修改,而是使用代理工廠的模式 使用代理類來實現你想的功能

      應用

      1. 遠程代理: 爲一個對象在不用的地址空間提供局部表明,這樣能夠隱藏一個對象存在於不一樣地址空間的事實。
      2. 虛擬代理:根據須要建立開銷很大的對象。經過它來存放實例化須要很長時間的真實對象。
      3. 安全代理:用來控制真實對象訪問時的權限
      4. 智能指引:指調用真實對象時,代理處理另一些事。
        應用實例
      • 火車票不只能夠在火車站買也能夠在車代售點買。
      • 一我的A變換成另外一我的B的模樣,將B的外貌抽象出來,A B都實現了這個接口,用戶C訪問A的時候 看不出A不是B 因此可說A是B的代理類。 以說A是B的代理類。

      代理模式的分類

      • 代理的實現 聚合和繼承

      動態代理模式(不知道代理類的名稱 直接產生代理對象)

      解決類太多的問題

      • 繼承:不宜與擴展

      • 聚合(使用接口的方式):一個類A中有另一個類B的對象(接口),兩個類實現相同的接口,可是在一個類A中調用的是另外一個類B的方法。 A就是B的一個代理,由於在A中調用的方法是B的方法

        • 經過接口來實現代理
        • 比較靈活,能夠隨意地調換代理事務的順序。
      • 實現動態的編譯

        • JavaCompiler(java的編譯器 javac)

      靜態代理(須要知道代理類的類名)

      一個代理類 和 觸發人 實現接口 一個代理類只有一個功能

      • 實現動態代理模式的方式有兩種:

        • 依賴jdk的Proxy對象下的newProxyInstance()

          • 注意事項:必需要救要有事件,委託人必需要實現事件接口
          • 代理人實現InvocationHander接口 重寫invoke方法 在invoke方法中作一些代理的額處理,經過method.invoke(this.obj,args) 來調用委託人的方法
          • 調用的時候將代理人和委託人經過(代理類)Procy.newProxyInstance(委託類.getClassLoader(),委託類.getInterfaces(),代理類);
        • cglib字節碼修改器實現代理

          • 於jdk中的實現動態代理方式不一樣的就是,委託人不須要實現特定的接口
          • 須要導入 ams.jar 和 cglib.jar 和 javassist.jar
          • 核心類 Enhancer
          • 委託類不須要實現接口, 代理類要實現MethodInterceptor接口 使用回調的方法,效率比proxy要快
          • 在代理類中寫createProxy方法
        public Object createProxy(Object target){
        this.obj = target;
        Enhancer enhancer = new Enhancer();
        //設置被代理對象目標
        enhancer.setSuperclass(this.obj.getClass());
        //回調  調用下面的intercept(..)方法
        enhancer.setCallback(this);
        enhancer.setClassLoader(target.getClass().getClassLoader());
        return enhancer.create();

         

      • 調用:
      Target t = new Target(); MyProxy my = new MyProxy(); Target t2 = (Target) my.createProxy(t); t2.getMsg("sdsf");
      
相關文章
相關標籤/搜索