cglib動態代理

概念及特點

  • 使用CGLib實現動態代理,依賴cglib-x.x.x.jar
  • 原理是對指定的業務類動態生成一個子類,並覆蓋其中業務方法實現代理
  • 針對類來實現代理的,完全不受代理類必須實現接口的限制
  • CGLib底層採用ASM字節碼生成框架,使用字節碼技術生成代理類
  • 因爲採用的是繼承,所以不能對final修飾的類進行代理,不能對聲明爲final的方法進行代理

組成

  • 業務實現類 負責實現主要的業務方法(不需要實現接口)
  • 實現攔截接口MethodInterceptor,創建動態代理類

案例演示

  1. 引入cglib

        <dependencies>
            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2.2</version>
            </dependency>
        </dependencies>
    
  2. 業務實現類

    public class AccountServiceImpl {
        public void queryAccount() {
            System.out.println("查看賬戶...");
        }
    
        public void updateAccount() {
            System.out.println("修改賬戶...");
        }
    }
    
  3. 方法攔截器

    public class CglibProxy implements MethodInterceptor {
        private Object target;//業務類對象,供代理方法中進行真正的業務方法調用
    
        //相當於JDK動態代理中的綁定
        public Object getInstance(Object target) {
            this.target = target;  //給業務對象賦值
            Enhancer enhancer = new Enhancer(); //創建加強器,用來創建動態代理類
            enhancer.setSuperclass(this.target.getClass());  //爲加強器指定要代理的業務類(即:爲下面生成的代理類指定父類)
            //設置回調:對於代理類上所有方法的調用,都會調用CallBack,而Callback則需要實現intercept()方法進行攔截
            enhancer.setCallback(this);
            // 創建動態代理類對象並返回
            return enhancer.create();
        }
    
        // 實現回調方法
        @Override
        public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("預處理——————");
            proxy.invokeSuper(target, args); //調用業務類(父類中)的方法
            System.out.println("調用後操作——————");
            return null;
        }
    }
    
    1. 業務調用
      public class CglibProxyApplication {
          public static void main(String[] args) {
              AccountServiceImpl accountServiceImpl=new AccountServiceImpl();
              CglibProxy  cglib=new CglibProxy();
              AccountServiceImpl accountServiceProxy=(AccountServiceImpl)cglib.getInstance(accountServiceImpl);
              accountServiceProxy.queryAccount();
              accountServiceProxy.updateAccount();
          }
      }
    

兩種動態代理對比

  1. 機制區別
  • jdk動態代理是通過接口中的方法名,在動態生成的代理類中調用業務實現類的同名方法;利用攔截器(攔截器必須實現InvocationHanlder)加上反射機制生成一個實現代理接口的匿名類;
  • cglib動態代理是通過繼承業務類,生成的動態代理類是業務類的子類,通過重寫業務方法進行代理;cglib底層採用ASM字節碼生成框架,使用字節碼技術生成代理類;
  1. 效率對比
  • jdk6之前,cglib效率過於jdk反射
  • 調用次數較少時,jdk6、jdk7優於cglib
  • 調用次數較多時,jdk6、jdk7反射效率低於cglib
  • jdk8 動態代理優於cglib效率
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章