一分钟看懂动态代理
動態(tài)代理:
在不改變目標(biāo)對象方法的情況下對方法進(jìn)行增強(qiáng)
組成部分:
- 被代理對象:真實(shí)的對象
- 代理對象:內(nèi)存中的一個對象
要求:
代理對象必須和被代理對象實(shí)現(xiàn)相同的接口
實(shí)現(xiàn)
使用Proxy.newProxyInstance()
舉栗子:
1.現(xiàn)實(shí)生活代理
賣票接口:抽象對象,規(guī)定要有賣票的方法
你買火車票 -> 黃牛 -> 12306
你買電腦 -> 電腦的代理商 -> 電腦廠家
2.代理模式三要素
1.真實(shí)對象: 12306
2.代理對象: 黃牛
3.抽象對象: 賣票的接口
3.什么是動態(tài)代理
在程序運(yùn)行的過程中創(chuàng)建代理對象
4.代理模式好處
1.對方法進(jìn)行增強(qiáng)
2.可以攔截方法
5.動態(tài)代理的API
Proxy類:
- static Object newProxyInstance?(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)創(chuàng)建代理對象
- 返回值Object: 創(chuàng)建出代理對象
- ClassLoader loader: 類加載器
- Class<?>[] interfaces: 接口數(shù)組, 新建的代理對象會實(shí)現(xiàn)指定的接口
- InvocationHandler h: 執(zhí)行處理器, 當(dāng)代理對象調(diào)用方法時,就會執(zhí)行InvocationHandler的invoke方法
演示:
要求在不改變Student類的前提下,將趴著學(xué)習(xí)改成站著學(xué)習(xí)
學(xué)生類:
接口類:
public interface StudentInterface {void eat(String name);void study(); }測試類:
public class Test {public static void main(String[] args) {Student student = new Student();// 需求:在不改變Student類代碼前提下,通過study方法輸出,站著學(xué)習(xí)/*參數(shù)一:類加載器:和被代理對象使用相同的類加載器參數(shù)二:接口類型Class數(shù)組:和被代理對象使用相同接口參數(shù)三:完成代理增強(qiáng)的功能*/StudentInterface sp = (StudentInterface) Proxy.newProxyInstance(student.getClass().getClassLoader(), new Class[]{StudentInterface.class}, new InvocationHandler() {// 執(zhí)行Student類中所有方法都會經(jīng)過invoke方法,對method方法判斷,是想要的方法就可以處理@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (method.getName().equals("study")) {System.out.println("站著學(xué)習(xí)");return null;} else {return method.invoke(student, args);}}});sp.eat("包子");sp.study();} }總結(jié)
- 上一篇: jsoup 去除html标签,如何使用j
- 下一篇: php instanceof 基类,PH