JDK動態代理和CGLib代理

今天國慶節第三天,學習複習spring的實現AOP思想所使用的的原理,主要是JDK動態代理和CGLib動態代理

第一:JDK動態代理

概念:利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理
條件:接口+實現類
缺陷:不能代理實現類,無接口

第二:CGLib(code generize library)

概念:利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理,相當於繼承,然後對方法進行增強處理,所以被代理類不能被final修飾
條件:實現類
缺陷:必須依賴於CGLib的類庫

實現步驟:

  1. 創建一個實現接口InvocationHandler的類,它必須實現invoke方法
  2. 創建被代理的類以及接口
  3. 通過Proxy的靜態方法 newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)創建一個代理
  4. 通過代理調用方法

jdk代理實現

第一步:創建接口和實現類

public interface ItemsService {
     //測試jdk代理,cglib不需要接口
     void jdkProxy();
}
public class ItemsServiceImpl implements ItemsService {
    public void jdkProxy() {
        System.out.println("jdk測試代理方式被執行");
    }
    public void cglibProxy() {
        System.out.println("cglb測試代理方式被執行");
    }
  }

第二步:創建切面增強類

public class MyAspect {
    public void before(){
        System.out.println("before");
    }
    public void after(){
        System.out.println("after");
    }
}

第三步:創建動態代理工具類

public class JDKProxyFactory {
    //增強的類
    final static MyAspect myAspect=new MyAspect();

    //代理創建實例,參數o代表創建的一個空對象
    public static Object createInstance(final Object o){

    //參數一:類加載器,參數二:接口名,參數三:自定義增強類,採取匿名自定義

      Object object= Proxy.newProxyInstance(o.getClass().getClassLoader(), o.getClass().getInterfaces(), new InvocationHandler() {

            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
               //加入增強的方法
                myAspect.before();
                //執行原來的方法
                Object o1=method.invoke(o,args);
                myAspect.after();
                return o1;
            }
        });
        //返回代理對象
        return object;
    }
}
第四步:測試

public class ProxyTest {

@Test
public void test1(){
    //創建一個空對象
    ItemsService itemsService=new ItemsServiceImpl();
    //創建代理對象實例
    ItemsService itemsService1= (ItemsService) JDKProxyFactory.createInstance(itemsService);
    try {
        //測試方法
        itemsService1.jdkProxy();
    } catch (Exception e) {
        e.printStackTrace();
    }
}    

這裏寫圖片描述

cglib代理實現

第一步:創建實現類,不能被final修飾,見jdk代理實現類
第二步:創建增強類,見jdk代理實現
第三步:編寫代理類
因爲cglib是對指定的類先創建其子類,然後實現其所有方法,所以這裏這是對itemsSrviceImpl類進行代理

public class CglibProxyFactory {
    //增強的類
    final static MyAspect myAspect=new MyAspect();

    public static ItemsServiceImpl  createProxy(Object o){
        //創建類的子類
        final ItemsServiceImpl itemsService=new ItemsServiceImpl();
        //創建核心類
        Enhancer enhancer=new Enhancer();
        //設置父類
        enhancer.setSuperclass(itemsService.getClass());
        //代理類實現回調方法,類似jdk代理的增強器
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //設置增強方法
                myAspect.before();

                Object obj=method.invoke(itemsService,args);
                //methodProxy.invokeSuper(proxy,args);
                //設置增強方法
                myAspect.after();

                return obj;
            }
        });
        return (ItemsServiceImpl) enhancer.create();
    }
}

第四步:測試

 @Test
    public void test2(){
        ItemsServiceImpl itemsService1= CglibProxyFactory.createProxy(new ItemsServiceImpl());
        try {
            //測試方法
            itemsService1.cglibProxy();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

結果爲:
這裏寫圖片描述

總結:

jdk代理源碼見:http://blog.csdn.net/jiankunking/article/details/52143504

發佈了63 篇原創文章 · 獲贊 17 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章