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

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

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

      淺談代理模式

      2022年04月06日 第一版
      2023年12月13日 第二版本更新,學而時習,思則常新

      1. 代理模式

      拋開精密的學術用語,就是在不修改原來對象的前提下,提供額外的功能與操作。

      2. 分類

      下面先展示幾個類,JDKCGLIB 共同會用:一個接口+ 一個實現類

      /**
       * @author: handsometaoa
       * @description
       * @date: 2023/12/13 11:43
       */
      public interface UserService {
          String showMsg();
      }
      
      /**
       * @author: handsometaoa
       * @description
       * @date: 2023/12/13 11:44
       */
      @Service
      public class UserServiceImpl implements UserService {
          @Override
          public String showMsg() {
              System.out.println("展示消息");
              return "返回信息";
          }
      }
      

      2.1 靜態代理:

      現在我有一個功能,想要在方法A前后加日志、加控制權限、加審計,但是我不想修改A方法。

      雖然你只添加了日志,出事都找你??

      那就可以把 【日志+被代理對象.方法(舊方法)+日志】作為新方法。

      代理類:

      public class UserServiceLogProxy implements UserService {
          private final UserService userService;
          
          public UserServiceLogProxy(UserService userService) {
              this.userService = userService;
          }
      
          @Override
          public void sayHello() {
              System.out.println("開始記錄日志");
              userService.showMsg();
              System.out.println("結束記錄日志");
          }
      }
      

      缺點:

      比如說,我現在有100個類似的方法,都需要加日志,我需要寫100個代理類。

      按道理(開始講道理了)日志信息是功能相同的,可以復用。


      2.2 動態代理

      我們設想可以把日志方法抽象出去,動態插入各個想記錄日志的方法,熱插拔(這個詞妙,生動形象),美哉。

      2.2.1 JDK 動態代理

      實現步驟:

      1. 定義一個接口及其實現類
      2. 實現 InvocationHandler (java.lang.reflect.InvocationHandler) 并重寫 invoke 方法,在 invoke 方法中我們會調用原生方法(被代理類方法)并增加自定義邏輯(日志等功能)
      3. 通過 Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) 方法創建代理對象

        JDK代理有一個缺點就是只能代理實現接口的類

        public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler);
        

      代碼:

      import java.lang.reflect.InvocationHandler;
      import java.lang.reflect.Method;
      import java.lang.reflect.Proxy;
      
      /**
       * @author: handsometaoa
       * @description JDK動態代理,基于接口
       * @date: 2023/12/13 11:55
       */
      public class LogProxyJdk implements InvocationHandler {
          private final Object target;
      
          public LogProxyJdk(Object target) {
              this.target = target;
          }
      
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
              System.out.println("開始記錄日志");
              Object result = method.invoke(target, args);
              System.out.println("結束記錄日志");
              return result;
          }
      
          /**
           * 獲取代理對象
           */
          public Object getProxy() {
              return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
          }
      }
      

      使用:

      @RestController
      @RequestMapping("dynamic")
      public class DynamicController {
          @Resource
          private UserService userService;
      
          @RequestMapping("/jdk")
          String jdk() {
              LogProxyJdk logProxyJdk = new LogProxyJdk(userService);
              UserService proxy = (UserService) logProxyJdk.getProxy();
              return proxy.showMsg();
          }
      }
      

      缺點:

      JDK動態代理只能代理有接口的方法,如果被代理類未實現接口,我們可以用 CGLIB 動態代理機制來實現。

      2.2.2 CGLIB 動態代理

      實現步驟:

      1. 定義一個類
      2. 實現 MethodInterceptor (org.springframework.cglib.proxy.MethodInterceptor) 并重寫 intercept 方法,intercept 用于攔截增強被代理類的方法
      3. 通過 Enhancer 類的 create() 方法創建代理類 ,設置父類及回調類,檢測到攔截方法時會調用 intercept 方法。
        CGLIB 通過 fast-class 來提高效率,首先將方法都建立索引,然后通過索引快速查找,來調用方法

      代碼:

      import org.springframework.cglib.proxy.Enhancer;
      import org.springframework.cglib.proxy.MethodInterceptor;
      import org.springframework.cglib.proxy.MethodProxy;
      import java.lang.reflect.Method;
      
      /**
       * @author: handsometaoa
       * @description CGLIB 動態代理
       * @date: 2023/12/13 11:43
       */
      public class LogProxyCglib implements MethodInterceptor {
      
          private final Class clazz;
      
          public LogProxyCglib(Class clazz) {
              this.clazz = clazz;
          }
      
          public Object getProxy() {
              Enhancer enhancer = new Enhancer();
              enhancer.setSuperclass(clazz); // 設置父類
              enhancer.setCallback(this); // 設置回調,設置為 this,當調用攔截方法時,會調用攔截器的 intercept 方法
              return enhancer.create();
          }
      
          /**
           * @param object      表示要攔截的對象,即被代理的對象。
           * @param method      表示要攔截的方法,即被代理對象的方法。
           * @param args        表示方法的參數列表,即被代理對象方法的參數。
           * @param methodProxy 表示用于調用原始方法的代理對象。
           */
          @Override
          public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
              System.out.println("開始記錄日志");
              Object result = methodProxy.invokeSuper(object, args);
              System.out.println("結束記錄日志");
              return result;
          }
      
      
      }
      
      
      

      使用

      @RestController
      @RequestMapping("dynamic")
      public class DynamicController {
          @RequestMapping("/cglib")
          String cglib(){
              LogProxyCglib logProxyCglib = new LogProxyCglib(UserServiceImpl.class);
              UserService proxy = (UserService) logProxyCglib.getProxy();
              return proxy.showMsg();
          }
      }
      

      3. 參考文獻 站在前人的腳上,踏步前進。

      1. 漫畫:AOP 面試造火箭事件始末
      2. Java動態代理-最通俗易懂的動態代理
      3. cglib動態代理原理和源碼
      posted @ 2022-04-06 19:06  帥氣的濤啊  閱讀(49)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 无码乱人伦一区二区亚洲| 国产精品无码成人午夜电影| 汝南县| 91精品午夜福利在线观看| 国产一级r片内射免费视频| 亚洲一本二区偷拍精品| 国产麻豆剧传媒精品国产av| 亚洲 日韩 国产 制服 在线| 国产精品一区二区蜜臀av| 久久91精品牛牛| 欧洲中文字幕一区二区| 日韩国产成人精品视频| 野外做受三级视频| 国产福利一区二区三区在线观看| 亚洲AV高清一区二区三区尤物| 亚洲自在精品网久久一区| 蜜桃在线一区二区三区| 国产仑乱无码内谢| 国产成人精品亚洲高清在线| 开心一区二区三区激情| 精品一区二区三区东京热| 日本免费人成视频在线观看| 亚洲熟妇一区二区三个区| 久久精品蜜芽亚洲国产av| 精品综合久久久久久97| 亚洲av色综合久久综合| 日韩美a一级毛片| 国产福利在线观看免费第一福利| 亚洲国产精品久久久久秋霞| 久久99精品九九九久久婷婷| 郓城县| 亚洲日韩AV秘 无码一区二区| 中文字幕日韩有码国产| 国产偷国产偷亚洲清高网站| 激情综合色综合啪啪开心| 久久精品国产www456c0m| 精品一区二区三区无码视频| 成人动漫在线观看| 忘忧草在线社区www中国中文| 日韩亚洲国产中文字幕欧美 | 亚洲乱熟乱熟女一区二区|