ssm學習筆記——spring——動態代理

動態代理:

       特點:字節碼隨用隨創建,隨用隨加載
       作用:不修改源碼的基礎上對方法增強
       分類:
           基於接口的動態代理
           基於子類的動態代理

基於接口的動態代理:

           涉及的類:Proxy
           提供者:JDK官方
       如何創建代理對象:
           使用Proxy類中的newProxyInstance方法
       創建代理對象的要求:
           被代理類最少實現一個接口,如果沒有則不能使用
       newProxyInstance方法的參數:
           ClassLoader:類加載器
               它是用於加載代理對象字節碼的。和被代理對象使用相同的類加載器。固定寫法。
           Class[]:字節碼數組
               它是用於讓代理對象和被代理對象有相同方法。固定寫法。
           InvocationHandler:用於提供增強的代碼
               它是讓我們寫如何代理。我們一般都是些一個該接口的實現類,通常情況下都是匿名內部類,但不是必須的。
               此接口的實現類都是誰用誰寫。
IProducer proxyProducer = (IProducer) Proxy.newProxyInstance(producer.getClass().getClassLoader(),
    producer.getClass().getInterfaces(),
    new InvocationHandler() {
    /**
    * 作用:執行被代理對象的任何接口方法都會經過該方法
    * 方法參數的含義
    * @param proxy   代理對象的引用
    * @param method  當前執行的方法
    * @param args    當前執行方法所需的參數
    * @return        和被代理對象方法有相同的返回值
     * @throws Throwable
     */
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //提供增強的代碼
       Object returnValue = null;

       //1.獲取方法執行的參數
       Float money = (Float)args[0];
       //2.判斷當前方法是不是銷售
       if("saleProduct".equals(method.getName())) {
        returnValue = method.invoke(producer, money*0.8f);
         }
        return returnValue;
      }
     });

基於子類的動態代理:

           涉及的類:Enhancer
           提供者:第三方cglib庫
       如何創建代理對象:
           使用Enhancer類中的create方法
       創建代理對象的要求:
           被代理類不能是最終類
       create方法的參數:
           Class:字節碼
               它是用於指定被代理對象的字節碼。       
           Callback:用於提供增強的代碼
               它是讓我們寫如何代理。我們一般都是些一個該接口的實現類,通常情況下都是匿名內部類,但不是必須的。
               此接口的實現類都是誰用誰寫。
               我們一般寫的都是該接口的子接口實現類:MethodInterceptor
Producer cglibProducer = (Producer)Enhancer.create(producer.getClass(), new MethodInterceptor() {
       /**
        * 執行被創建對象的任何方法都會經過該方法
        * @param proxy
        * @param method
        * @param args
        *    以上三個參數和基於接口的動態代理中invoke方法的參數是一樣的
        * @param methodProxy :當前執行方法的代理對象
        * @return
        * @throws Throwable
        */
       @Override
       public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
           //提供增強的代碼
           Object returnValue = null;

           //1.獲取方法執行的參數
           Float money = (Float)args[0];
           //2.判斷當前方法是不是銷售
           if("saleProduct".equals(method.getName())) {
               returnValue = method.invoke(producer, money*0.8f);
           }
           return returnValue;
       }
   });
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章