您好,登錄后才能下訂單哦!
本文實例講述了Java動態(tài)代理實現(xiàn)方法。分享給大家供大家參考,具體如下:
靜態(tài)代理了解的差不多了,但是對于動態(tài)代理理解的還不是很通透,這里先把一些常用的動態(tài)代理實現(xiàn)方法記錄下來,日后時常看看爭取早日融會貫通。
1、JDK實現(xiàn)動態(tài)代理
主要使用了Proxy.newProxyInstance()方法,該方法的官方解釋為:返回一個指定接口的代理類實例,該接口可以將方法調(diào)用指派到指定的調(diào)用處理程序。
public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目標(biāo)類:代理類要增強(qiáng)的類 public class SomeServiceImpl implements ISomeService { @Override public String doFirst() { return "AAAbbb"; } @Override public void doSecond() { System.out.println("SomeServiceImpl:執(zhí)行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:目標(biāo)方法 // args:目標(biāo)方法的參數(shù)列表 @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實現(xiàn)動態(tài)代理(沒接口)
使用JDK的Proxy實現(xiàn)動態(tài)代理,要求目標(biāo)類與代理類實現(xiàn)相同的接口,若目標(biāo)類不存在接口,則無法使用該方式實現(xiàn)。
對于沒有接口的類,要為其創(chuàng)建動態(tài)代理,就要使用CGLIB來實現(xiàn)。CGLIB動態(tài)代理的生成原理是生成目標(biāo)類的子類,而子類是增強(qiáng)過的,這個子類對象就是代理對象。使用CGLIB生成代理類,要求目標(biāo)類必須能被繼承,因此不能是final類。
//目標(biāo)類:代理類要增強(qiáng)的類 public class SomeService { public String doFirst() { System.out.println("SomeServiceImpl:執(zhí)行doFirst()"); return "AAAbbb"; } public void doSecond() { System.out.println("SomeServiceImpl:執(zhí)行doSecond()"); } } //注意:使用Cglib動態(tài)代理,要求目標(biāo)類不能是final的 //Cglib動態(tài)代理的增強(qiáng)原理是:子類增強(qiáng)父類,所以目標(biāo)類必須能被繼承 public class CglibFactory implements MethodInterceptor { private SomeService target; public CglibFactory() { } public CglibFactory(SomeService target) { this.target = target; } public SomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父類,即目標(biāo)類。因為Cglib動態(tài)代理增強(qiáng)的原理是:子類增強(qiáng)父類 enhancer.setSuperclass(SomeService.class); //設(shè)置回調(diào)接口對象 enhancer.setCallback(this); //create()方法用于創(chuàng)建Cglib動態(tài)代理對象 return (SomeService)enhancer.create(); } //回調(diào)函數(shù)的執(zhí)行條件:代理對象執(zhí)行目標(biāo)方法時會觸發(fā)該方法 @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實現(xiàn)動態(tài)代理(有接口)
在有接口的情況下利用CGLIB實現(xiàn)動態(tài)代理跟沒有接口的情況下利用CGLIB實現(xiàn)動態(tài)代理,其實差不多。
public interface ISomeService { String doFirst(); void doSecond(); String doThird(); } //目標(biāo)類:代理類要增強(qiáng)的類 public class SomeService implements ISomeService { public String doFirst() { return "AAAbbb"; } public void doSecond() { System.out.println("SomeServiceImpl:執(zhí)行doSecond()"); } @Override public String doThird() { return "third"; } } //注意:使用Cglib動態(tài)代理,要求目標(biāo)類不能是final的 //Cglib動態(tài)代理的增強(qiáng)原理是:子類增強(qiáng)父類,所以目標(biāo)類必須能被繼承 public class CglibFactory implements MethodInterceptor { private ISomeService target; public CglibFactory() { } public CglibFactory(ISomeService target) { this.target = target; } public ISomeService myCglibCreator() { Enhancer enhancer = new Enhancer(); //指定父類,即目標(biāo)類。因為Cglib動態(tài)代理增強(qiáng)的原理是:子類增強(qiáng)父類 enhancer.setSuperclass(ISomeService.class); //設(shè)置回調(diào)接口對象 enhancer.setCallback(this); //create()方法用于創(chuàng)建Cglib動態(tài)代理對象 return (ISomeService)enhancer.create(); } //回調(diào)函數(shù)的執(zhí)行條件:代理對象執(zhí)行目標(biāo)方法時會觸發(fā)該方法 @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相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java面向?qū)ο蟪绦蛟O(shè)計入門與進(jìn)階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計有所幫助。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。