-
靜態(tài)代理:
代理和被代理對(duì)象在代理之前是確定的。他們都實(shí)現(xiàn)相同的接口或者繼承相同的抽象類
繼承
聚合
查看全部 -
代理的兩種實(shí)現(xiàn)方式:
靜態(tài)代理,動(dòng)態(tài)代理
查看全部 -
動(dòng)態(tài)代理步驟
查看全部 -
從java源文件,動(dòng)態(tài)手動(dòng)編譯成class,加載到內(nèi)存,調(diào)用方法查看全部
-
invocationhandler 轉(zhuǎn)換成自己寫的,然后把被代理類傳入
查看全部 -
靜態(tài)代理:代理和被代理對(duì)象在代理之前是確定的,他們都實(shí)現(xiàn)相同的接口或者繼承相同的抽象類
查看全部 -
代理模式的分類:?
遠(yuǎn)程代理模式:為不同地理的對(duì)象提供局域網(wǎng)代表對(duì)象(例子:通過(guò)遠(yuǎn)程代理可以監(jiān)控各個(gè)店鋪,使之可以直觀的了解店里的情況)
?虛擬代理:根據(jù)需要將資源消耗很大的對(duì)象進(jìn)行延遲,真正需要的時(shí)候進(jìn)行創(chuàng)建 (類似于新聞網(wǎng)站加載時(shí),圖片加載不出來(lái)先用一張空的圖片代替)
保護(hù)代理:控制用戶的訪問(wèn)權(quán)限?
智能引用代理:提供對(duì)目標(biāo)對(duì)象提供額外的服務(wù)(火車票代售處)
查看全部 -
cglib jdk
查看全部 -
car2實(shí)現(xiàn)代理
查看全部 -
總結(jié)回顧: 1、代理概念、分類及應(yīng)用場(chǎng)景 為其他對(duì)象設(shè)置總代理,以控制對(duì)這個(gè)對(duì)象的訪問(wèn); 代理對(duì)象起到了中介的作用,去掉了某些功能,或增加了些額外的服務(wù)。 四類: Remote Proxy -- 客戶端服務(wù)器的模式 Virtual Proxy -- 資源消耗很大,或復(fù)雜的對(duì)象,需要延遲,需要時(shí)創(chuàng)建, Protect Proxy -- 保護(hù)和控制權(quán)限 Smart Reference Proxy -- 提供額外服務(wù)。 為什么只講智能引用代理? 使用得多:日志處理、權(quán)限管理、事務(wù)處理... 靜態(tài)代理(繼承、聚合) JDK動(dòng)態(tài)代理實(shí)現(xiàn)日志處理的功能 模擬JDK動(dòng)態(tài)代理實(shí)現(xiàn):在代理類Proxy和被代理類RealSubject之間,加入了invocationHandler。 調(diào)用jar包中某個(gè)類的方法,不能改源碼,AOP面向切面,增加額外事務(wù)邏輯。
查看全部 -
上一講到代理,內(nèi)部的業(yè)務(wù)邏輯是硬編碼的,如何實(shí)現(xiàn)真正的動(dòng)態(tài)代理,動(dòng)態(tài)的指定業(yè)務(wù)邏輯呢? 1.需要?jiǎng)?chuàng)建一個(gè)事務(wù)處理器,首先創(chuàng)建一個(gè)接口也就是InvocationHandler,為了模擬JDK,這里把接口的名字和JDK事務(wù)處理器名稱一樣,同樣寫一個(gè)方法叫做invoke(),用來(lái)表示對(duì)某個(gè)對(duì)象的某個(gè)方法進(jìn)行業(yè)務(wù)處理,所以需要把某個(gè)對(duì)象以及對(duì)象的方法作為invoke()方法的參數(shù)傳遞進(jìn)來(lái),invoke(Object obj,Method method),方法作為參數(shù)使用到了java反射,需要把此包引入。這樣InvocationHandler接口就完成了。 2.創(chuàng)建事務(wù)處理實(shí)現(xiàn)類比如說(shuō)時(shí)間代理TimerProxy,實(shí)現(xiàn)了InvocationHandler接口,這樣結(jié)構(gòu)就成了 public class TimerProxy implements InvocationHandler{ @Override public void invoke(Object o, Method m) { ? ? ?//業(yè)務(wù)邏輯 ? ? ?method.invoke(目標(biāo)對(duì)象,參數(shù)); ? ? ?//業(yè)務(wù)邏輯 ? ? ? ?} 需要將目標(biāo)對(duì)象傳入,沒(méi)有參數(shù)可以不寫參數(shù),創(chuàng)建代理對(duì)象的構(gòu)造方法,初始化目標(biāo)對(duì)象 3.在Proxy類的newProxyInstance()方法中,除了要把目標(biāo)Class接口作為參數(shù)外,還需要把事務(wù)處理器InvocationHandler 傳進(jìn)去,然后更改創(chuàng)建實(shí)例對(duì)象中硬編碼的部分用事務(wù)處理器方法替代即可。難點(diǎn)在于字符串的拼接。
查看全部 -
完善動(dòng)態(tài)代理實(shí)現(xiàn) 首先得到系統(tǒng)編譯器,通過(guò)編譯器得到文件管理者,以獲取文件,然后編譯器執(zhí)行編譯任務(wù),完成編譯之后,將class文件加載到類加載器中,通過(guò)構(gòu)造方法得到實(shí)例,然后調(diào)用newInstance()接收一個(gè)對(duì)象的實(shí)例并返回。 (1)拿到編譯器 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); (2)文件管理者 StandardJavaFileManager fileMgr = Compiler.getStandardFileManager(null,null,null); (3)獲取文件 Iterable units = fileMgr.getJavaFileObjects(filename); (4)編譯任務(wù) CompilationTask t =compiler.getTask(null,fileMgr,null,null,null,units); (5)load到內(nèi)存 ClassLoader cl = ClassLoader.getSystemClassLoader(); Class c = cl.loadClass(”com.imooc.proxy.$Proxy0”); (6)通過(guò)代理對(duì)象的構(gòu)造器構(gòu)造實(shí)例,并返回代理對(duì)象 Constructor ctr = c.getConstructor(infce); return ctr.newInstance(new Car());
查看全部 -
自己實(shí)現(xiàn)JDK動(dòng)態(tài)代理的思路: 實(shí)現(xiàn)功能:通過(guò)Proxy的newProxyInstance()返回代理對(duì)象 1. 聲明一段源碼(動(dòng)態(tài)產(chǎn)生代理,Java的文件名要注意--$Proxy0) 2. 編譯源碼(JDK Compiler API),產(chǎn)生新的類(代理類) 3. 將這個(gè)類load到內(nèi)存當(dāng)中,產(chǎn)生一個(gè)新的對(duì)象(代理對(duì)象) 4. return代理對(duì)象 設(shè)置換行符:String rt = "\r\n"; 獲取文件路徑:String fileName = System.getProperty("user.dir")+"/bin/com/imooc/proxy/$Proxy.java";
查看全部 -
JDK自從1.3版本開始,就引入了動(dòng)態(tài)代理,JDK的動(dòng)態(tài)代理用起來(lái)非常簡(jiǎn)單,但是它有一個(gè)限制,就是使用動(dòng)態(tài)代理的對(duì)象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口 。如果想代理沒(méi)有實(shí)現(xiàn)接口的類可以使用CGLIB包。 CGLIB(Code Generation Library)是一個(gè)開源項(xiàng)目。是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫(kù),它可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口。Hibernate用它來(lái)實(shí)現(xiàn)PO(Persistent Object 持久化對(duì)象)字節(jié)碼的動(dòng)態(tài)生成。 注意:CGLIB不能對(duì)“final”修飾的類進(jìn)行代理。 相關(guān)代碼——(下): @CglibProxy.java public class CglibProxy implements MethodInterceptor { private Enhancer enhancer=new Enhancer(); public Object getProxy(Class cls){ //設(shè)置創(chuàng)建子類的類 enhancer.setSuperclass(cls); enhancer.setCallback(this); return enhancer.create(); } /** * 參數(shù):object:攔截所有目標(biāo)類方法的調(diào)用,method:目標(biāo)方法的反射對(duì)象,args:方法的參數(shù),methodproxy:代理類的實(shí)例。 */ public Object intercept(Object object, Method method, Object[] args, MethodProxy methodproxy) throws Throwable { syso("日志開始..."); methodproxy.invokeSuper(object, args); syso("日志結(jié)束..."); return null; } }
查看全部 -
@設(shè)計(jì)模式——代理模式——了解JDK動(dòng)態(tài)代理 一、JDK動(dòng)態(tài)代理 1、目的:動(dòng)態(tài)產(chǎn)生代理,實(shí)現(xiàn)對(duì)【不同類】,【不同方法】的代理 2、java動(dòng)態(tài)代理類,位于java.lang.reflect包下,一般涉及兩個(gè)類: (1)Interface InvocationHandler:該接口中僅定義了一個(gè)方法public object invoke(obj,method,args):實(shí)際使用中,obj指被代理類的對(duì)象,method指被代理的方法,args為該方法參數(shù)數(shù)組。這個(gè)抽象方法在代理類中動(dòng)態(tài)實(shí)現(xiàn) (2)Proxy:該類即為動(dòng)態(tài)代理類:static Object newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler h):返回代理類的一個(gè)實(shí)例,返回后的代理類可以被當(dāng)作代理類使用(可使用被代理類的在【接口中】聲明過(guò)的方法)。 · 第一個(gè)參數(shù)loader為被代理類的加載器,通過(guò)被代理類.getClass().getClassLoader()得到 · 第二個(gè)參數(shù)interfaces為被代理類實(shí)現(xiàn)的所有接口,同樣通過(guò)getClass().getInterface()得到 · 第三個(gè)參數(shù)handler就是自己實(shí)現(xiàn)的InvocationHandler的實(shí)現(xiàn)類的對(duì)象 3、***實(shí)現(xiàn): · 聲明一個(gè)代理h實(shí)現(xiàn)InvocationHandler接口,通過(guò)【構(gòu)造方法接受被代理類】,并實(shí)現(xiàn)invoke方法,添加業(yè)務(wù)邏輯(實(shí)現(xiàn)原有功能并添加額外功能) · 在測(cè)試類中,通過(guò)共同實(shí)現(xiàn)接口的實(shí)例獲得代理對(duì)象,并實(shí)現(xiàn)方法,如Interface1 i = (Interface1)Proxy.newProxyInstance(classLoader,classInterfaces,h); · 通過(guò)動(dòng)態(tài)代理對(duì)象m,代用其方法i.fun();
查看全部
舉報(bào)