Java動態(tài)代理實現(xiàn)方法小結(jié)
本文實例講述了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(); } //目標類:代理類要增強的類 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:目標方法 // args:目標方法的參數(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)代理,要求目標類與代理類實現(xiàn)相同的接口,若目標類不存在接口,則無法使用該方式實現(xiàn)。
對于沒有接口的類,要為其創(chuàng)建動態(tài)代理,就要使用CGLIB來實現(xiàn)。CGLIB動態(tài)代理的生成原理是生成目標類的子類,而子類是增強過的,這個子類對象就是代理對象。使用CGLIB生成代理類,要求目標類必須能被繼承,因此不能是final類。
//目標類:代理類要增強的類 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)代理,要求目標類不能是final的 //Cglib動態(tài)代理的增強原理是:子類增強父類,所以目標類必須能被繼承 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動態(tài)代理增強的原理是:子類增強父類 enhancer.setSuperclass(SomeService.class); //設置回調(diào)接口對象 enhancer.setCallback(this); //create()方法用于創(chuàng)建Cglib動態(tài)代理對象 return (SomeService)enhancer.create(); } //回調(diào)函數(shù)的執(zhí)行條件:代理對象執(zhí)行目標方法時會觸發(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(); } //目標類:代理類要增強的類 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)代理,要求目標類不能是final的 //Cglib動態(tài)代理的增強原理是:子類增強父類,所以目標類必須能被繼承 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動態(tài)代理增強的原理是:子類增強父類 enhancer.setSuperclass(ISomeService.class); //設置回調(diào)接口對象 enhancer.setCallback(this); //create()方法用于創(chuàng)建Cglib動態(tài)代理對象 return (ISomeService)enhancer.create(); } //回調(diào)函數(shù)的執(zhí)行條件:代理對象執(zhí)行目標方法時會觸發(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計入門與進階教程》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java操作DOM節(jié)點技巧總結(jié)》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
相關(guān)文章
springboot+RabbitMQ+InfluxDB+Grafara監(jiān)控實踐
這篇文章主要介紹了springboot+RabbitMQ+InfluxDB+Grafara監(jiān)控實踐,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07Java實現(xiàn)讀取項目中文件(.json或.properties)的方法詳解
這篇文章主要為大家詳細介紹了Java實現(xiàn)讀取項目中文件的方法,例如.json或.properties,文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下2023-04-04Nacos1.4.0 Windows10單機模式啟動和集群啟動過程解析
這篇文章主要介紹了Nacos1.4.0 Windows10單機模式啟動和集群啟動,第一次使用nacos,廢話不多說,記錄下自己啟動Nacos遇到的坑,感興趣的朋友跟隨小編一起看看吧2023-10-10