1. 程式人生 > >AOP之JDK動態代理和CGLib動態代理

AOP之JDK動態代理和CGLib動態代理

測試結果 edit print handle es2017 brush 類庫 構建 sets

一、JDK動態代理

JDK內置的Proxy動態代理可以在運行時動態生成字節碼,而沒必要針對每個類編寫代理類。中間主要使用到了一個接口InvocationHandler與Proxy.newProxyInstance靜態方法,參數說明如下:

使用內置的Proxy實現動態代理有一個問題:被代理的類必須實現接口,未實現接口則沒辦法完成動態代理。

1.編寫接口類

public interface IUserDao {
    public String add();
    public String edit();
}

2.編寫實現類

public class UserDaoImpl implements IUserDao {
    public String add() {
        System.out.println("add");
        return "add";
    }

    public String edit() {
        System.out.println("edit");
        return "edit";
    }
}

3.編寫測試類

    //JDK動態代理
    @Test
    public void  DTTest(){
       final IUserDao dao = new UserDaoImpl();
        IUserDao proxy =(IUserDao)Proxy.newProxyInstance(dao.getClass().getClassLoader(), dao.getClass().getInterfaces(), new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("事物已經開啟!");
                method.invoke(dao,args);
                return null;
            }
        });
        //代理對象add edit
        proxy.add();
        proxy.edit();
    } 

4.測試結果

技術分享

二、CGLIB動態代理

CGLIB(Code Generation Library)是一個開源項目,是一個強大的,高性能,高質量的Code生成類庫,它可以在運行期擴展Java類與實現Java接口,通俗說cglib可以在運行時動態生成字節碼。不需要有接口。

原理是:cglib繼承被代理的類,重寫方法,織入通知,動態生成字節碼並運行

cglib封裝了asm,可以在運行期動態生成新的class。

1.編寫業務類

public class UserService {
    //核心業務方法
    public void  deleter(){
        System.out.println("delete ok");
    }
}

2.編寫測試類

    //CGLIB動態代理
    @Test
    public void testCGlib() {
        //對方法進行增強,不破壞原有方法的業務
        //1.創建一個目標對象
        final UserService service = new UserService();
        //2.Enhancer對象
        Enhancer enhancer = new Enhancer();
        //3.在內存中構建業務類的子類    //設置父類
        enhancer.setSuperclass(service.getClass());

 /*  1、第一種方法
     enhancer.setCallback(new MethodInterceptor() {
            *//*
            * 第一個參數:Object為由CGLib動態生成的代理類實例
            * 第二個參數:Method為上文中實體類所調用的被代理的方法引用
            * 第三個參數:Object[]為參數值列表
            * 第四個參數:MethodProxy為生成的代理類對方法的代理引用
            * *//*
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("事物已經開啟");
                methodProxy.invoke(service,objects);
                return null;
            }
        });*/


        //4.調度setCallback     第二種方法
        enhancer.setCallback(new org.springframework.cglib.proxy.InvocationHandler() {
            public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
                System.out.println("事物已經開啟");
                method.invoke(service,objects);
                return null;
            }
        });
        //enhancer對象create方法創建出一個代理
        UserService proxy = (UserService)enhancer.create();
        //執行代理對象的deleter方法
        proxy.deleter();
    }

3.測試結果

技術分享

  

  

  

 

AOP之JDK動態代理和CGLib動態代理