您好,登錄后才能下訂單哦!
本文實例講述了Java動態代理實現方法。分享給大家供大家參考,具體如下:
靜態代理了解的差不多了,但是對于動態代理理解的還不是很通透,這里先把一些常用的動態代理實現方法記錄下來,日后時常看看爭取早日融會貫通。
1、JDK實現動態代理
主要使用了Proxy.newProxyInstance()方法,該方法的官方解釋為:返回一個指定接口的代理類實例,該接口可以將方法調用指派到指定的調用處理程序。
public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目標類:代理類要增強的類 public class SomeServiceImpl implements ISomeService { @Override public String doFirst() { return "AAAbbb"; } @Override public void doSecond() { System.out.println("SomeServiceImpl:執行doSecond()"); } @Override public String doThird() { return "aaa"; } } public class Mytest { public static void main(String[] args) { ISomeService target = new SomeServiceImpl(); ISomeService someService = (ISomeService) Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() { // proxy:代理對象 // method:目標方法 // args:目標方法的參數列表 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(target, args); if(result!=null) { result=((String)result).toUpperCase(); } return result; } }); System.out.println(someService.doFirst()); someService.doSecond(); System.out.println(someService.doThird()); } }
2、CGLIB實現動態代理(沒接口)
使用JDK的Proxy實現動態代理,要求目標類與代理類實現相同的接口,若目標類不存在接口,則無法使用該方式實現。
對于沒有接口的類,要為其創建動態代理,就要使用CGLIB來實現。CGLIB動態代理的生成原理是生成目標類的子類,而子類是增強過的,這個子類對象就是代理對象。使用CGLIB生成代理類,要求目標類必須能被繼承,因此不能是final類。
//目標類:代理類要增強的類 public class SomeService { public String doFirst() { System.out.println("SomeServiceImpl:執行doFirst()"); return "AAAbbb"; } public void doSecond() { System.out.println("SomeServiceImpl:執行doSecond()"); } } //注意:使用Cglib動態代理,要求目標類不能是final的 //Cglib動態代理的增強原理是:子類增強父類,所以目標類必須能被繼承 public class CglibFactory implements MethodInterceptor { private SomeService target; public CglibFactory() { } public CglibFactory(SomeService target) { this.target = target; } public SomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父類,即目標類。因為Cglib動態代理增強的原理是:子類增強父類 enhancer.setSuperclass(SomeService.class); //設置回調接口對象 enhancer.setCallback(this); //create()方法用于創建Cglib動態代理對象 return (SomeService)enhancer.create(); } //回調函數的執行條件:代理對象執行目標方法時會觸發該方法 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object invoke = method.invoke(target, args); if(invoke!=null) { invoke=((String)invoke).toUpperCase(); } return invoke; } } public class Mytest { public static void main(String[] args) { SomeService target = new SomeService(); SomeService proxy = new CglibFactory(target).myCglibCreator(); proxy.doFirst(); } }
3、CGLIB實現動態代理(有接口)
在有接口的情況下利用CGLIB實現動態代理跟沒有接口的情況下利用CGLIB實現動態代理,其實差不多。
public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目標類:代理類要增強的類 public class SomeService implements ISomeService { public String doFirst() { return "AAAbbb"; } public void doSecond() { System.out.println("SomeServiceImpl:執行doSecond()"); } @Override public String doThird() { return "third"; } } //注意:使用Cglib動態代理,要求目標類不能是final的 //Cglib動態代理的增強原理是:子類增強父類,所以目標類必須能被繼承 public class CglibFactory implements MethodInterceptor { private ISomeService target; public CglibFactory() { } public CglibFactory(ISomeService target) { this.target = target; } public ISomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父類,即目標類。因為Cglib動態代理增強的原理是:子類增強父類 enhancer.setSuperclass(ISomeService.class); //設置回調接口對象 enhancer.setCallback(this); //create()方法用于創建Cglib動態代理對象 return (ISomeService)enhancer.create(); } //回調函數的執行條件:代理對象執行目標方法時會觸發該方法 @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object invoke = method.invoke(target, args); if(invoke!=null) { invoke=((String)invoke).toUpperCase(); } return invoke; } } public class Mytest { public static void main(String[] args) { ISomeService target = new SomeService(); ISomeService proxy = new CglibFactory(target).myCglibCreator(); System.out.println(proxy.doFirst()); proxy.doSecond(); System.out.println(proxy.doThird()); } }
更多java相關內容感興趣的讀者可查看本站專題:《Java面向對象程序設計入門與進階教程》、《Java數據結構與算法教程》、《Java操作DOM節點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。