AOP之JDK動態代理和CGLib動態代理
阿新 • • 發佈:2017-10-12
測試結果 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動態代理