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

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

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

      JDK和CGLib動態代理

      一篇寫的很好的解釋動態代理原理的文章:

      博客原地址:http://www.rzrgm.cn/lifullmoon/p/14654836.html

      代理

      代理:在不改變原始代碼的情況下修改對象的行為。代理可以以透明的方式為對象添加額外的功能。

      言簡意賅:方法增強

      分類

      靜態代理

      人為編寫,編譯時就存在

      靜態代理就是通過實現被代理對象所實現的接口,內部保存了被代理對象,在實現的方法中對處理邏輯進行增強,實際的方法執行調用了被代理對象的方法。

      靜態代理實現步驟:

      • 定義一個接口及其實現類;

      • 創建一個代理類同樣實現這個接口

      • 將目標對象【實現類】注入進代理類,然后在代理類的對應方法調用目標類中的對應方法。

      這樣的話,我們就可以通過代理類屏蔽對目標對象的訪問,并且可以在目標方法執行前后做一些自己想做的事情。

      代碼示例:

      接口

      public interface Email {
          void sendEmail();
      }
      

      實現類

      public class EmailImpl implements Email{
          @Override
          public void sendEmail() {
              System.out.println("send email");
          }
      }
      

      代理類創建

      public class EmailProxy implements Email {
          private EmailProxy() {
          }
      
          private Email email;
      
          public EmailProxy(Email email) {
              this.email = email;
          }
      
          @Override
          public void sendEmail() {
              System.out.println("方法開始執行");
              email.sendEmail();
              System.out.println("方法執行結束");
          }
      }
      

      測試

      public class Test {
          public static void main(String[] args) {
              EmailProxy emailProxy = new EmailProxy(new EmailImpl());
              emailProxy.sendEmail();
          }
      }
      

      image-20240801084712166

      缺點:

      1、接口一旦新增方法,目標對象和代理對象都要進行修改

      2、每個代理類只能為一個接口服務,不能為多個接口服務【針對每個目標類都單獨創建一個代理類】

      ? 假設還有一個Phone的接口,又要再寫一個Phone的代理類,麻煩!

      3、代理類必須實現接口

      動態代理

      jdk動態代理

      運行時生成代理類,編譯時不存在

      解決了靜態代理每個代理類只能代理一個目標的問題,但是目標對象必須還是要實現接口

      代碼示例:

      代理類:Proxy.newProxyInstance()方法

      ? 參數:類加載器、目標對象實現的接口、處理接口方法調用的InvocationHandler處理器

      public class JDKProxyFactory {
          private JDKProxyFactory(){}
          public static Object getProxy(Object target){
              return Proxy.newProxyInstance(
                      target.getClass().getClassLoader(),
                      target.getClass().getInterfaces(),
                      new MyMethodInterceptor(target));
          }
      }
      

      處理器

      public class MyMethodInterceptor implements InvocationHandler {
          private final Object target;
      
          public MyMethodInterceptor(Object target){
              this.target = target;
          }
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("方法開始執行");
              Object res = method.invoke(target, args);
              System.out.println("方法執行結束");
              return res;
          }
      }
      

      測試

      public class Test {
          public static void main(String[] args) {
              Email email = (Email) JDKProxyFactory.getProxy(new EmailImpl());
              email.sendEmail();
      
              System.out.println("=================================");
      
              Phone phon = (Phone) JDKProxyFactory.getProxy(new PhoneImpl());
              phon.call();
          }
      }
      

      image-20240801090847107

      缺點:只能代理實現了接口的類

      為什么 JDK 動態代理只能基于接口代理,不能基于類代理?

      在JDK動態代理的底層代碼中,對于入參中的 interfaces 如果存在非接口,那么會拋出異常;且從生成的代理對象中看到會繼承 Proxy 這個類,在 Java 中類只能是單繼承關系,無法再繼承一個代理類,所以只能基于接口代理。

      CGLIB 動態代理

      【天空一聲巨響,cglib閃亮登場】

      CGLIB 通過繼承方式實現代理。

      CGLIB 動態代理基于類代理(字節碼提升),通過 ASM(Java 字節碼的操作和分析框架)將被代理類的 class 文件加載進來,通過修改其字節碼生成子類來處理。

      很多知名的開源框架都使用到了CGLIB,例如 Spring 中的 AOP 模塊中:

      如果目標對象實現了接口或者是代理類的子類,則默認采用 JDK 動態代理,否則采用 CGLIB 動態代理。

      image-20240801092715724

      CGLIB基本介紹:

      Code Generation Library代碼生成類庫,可以動態的給代理類生成一個子類,然后使用繼承方式重寫被代理方法

      CGLIB基本使用

      • 創建增強器對象Enhancer

      • 給增強器對象設置要代理的父類以及攔截器回調

      • 創建方法攔截器類,實現MethodInterceptor接口

      • 創建代理對象,并調用方法

      JDK 動態代理只能代理實現了接口的類或者直接代理接口,而 CGLIB 可以代理未實現任何接口的類。

      代碼示例:

      public class Email1 {
          public void sendEmail()
          {
              System.out.println("發送郵件");
          }
      }
      

      創建代理類

      public class CglibProxyFactory {
          private CglibProxyFactory(){}
      
          public static Object getProxy(Class<?> clazz)
          {
              Enhancer enhancer = new Enhancer();
              enhancer.setClassLoader(clazz.getClassLoader());
              enhancer.setSuperclass(clazz);
              enhancer.setCallback(new MyCallback());
              return enhancer.create();
          }
      }
      

      攔截器回調Callback

      因為 MethodInterceptor 繼承了 Callback 回調接口,所以可以傳入一個 MethodInterceptor 方法攔截器

      注意,如果你想設置一個 Callback[] 數組去處理不同的方法,那么需要設置一個 CallbackFilter 篩選器,用于選擇這個方法使用數組中的那個 Callback 去處理

      public class MyCallback implements MethodInterceptor {
          @Override
          public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
              System.out.println("before");
              Object result = proxy.invokeSuper(obj, args);
              System.out.println("after");
              return result;
          }
      }
      

      測試

      public class Test {
          public static void main(String[] args) {
              Email1 email = (Email1) CglibProxyFactory.getProxy(Email1.class);
              email.sendEmail();
          }
      }
      

      image-20240801093028672

      CGLIB 動態代理在 JVM 運行時會新生成一個代理類,這個代理對象繼承了目標類,也就是創建了一個目標類的子類,從而字節碼得到提升。

      posted @ 2025-02-24 16:39  kk小新  閱讀(72)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲国产色婷婷久久99精品91| 精品三级在线| 九九热免费在线视频观看| 中文字幕色偷偷人妻久久| 成人午夜av在线播放| 欧美国产成人精品二区芒果视频| 日本边添边摸边做边爱喷水| 中文字幕网红自拍偷拍视频| 久久久www成人免费精品| 无码日韩人妻精品久久| 国产精品先锋资源站先锋影院| 色欲狠狠躁天天躁无码中文字幕| 素人视频亚洲十一十二区| 蜜臀av人妻国产精品建身房| 国内自拍小视频在线看| 99久久亚洲综合精品成人网| 日本丰满熟妇hd| 欧美激情一区二区| 亚洲最大福利视频网| 18禁黄无遮挡网站免费| 日韩免费码中文在线观看| 亚洲国产精品综合久久网络| 国产乱码日产乱码精品精| 日本一区二区三深夜不卡| 影视先锋av资源噜噜| 亚洲国产一区二区三区| 亚洲av永久无码精品天堂久久| 丰满岳妇乱一区二区三区 | 亚洲av无码精品色午夜蛋壳| 精品国产一区二区三区香蕉| 无遮挡午夜男女xx00动态| 国语精品自产拍在线观看网站| 绥芬河市| 大又大又粗又硬又爽少妇毛片| xxxxbbbb欧美残疾人| 久久国产精品99久久蜜臀| 国产成人综合欧美精品久久| 国产精品福利中文字幕| 少妇撒尿一区二区在线视频| 日韩av一区二区精品不卡| 日韩一区二区三区女优丝袜|