您好,登錄后才能下訂單哦!
今天小編給大家分享一下Java代理模式實(shí)例代碼分析的相關(guān)知識(shí)點(diǎn),內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識(shí),所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
動(dòng)態(tài)代理的特點(diǎn):
當(dāng)代理對(duì)象的時(shí)候,不需要實(shí)現(xiàn)接口
代理對(duì)象的生成,是利用JDK的API,動(dòng)態(tài)的在內(nèi)存中構(gòu)建代理對(duì)象(需要我們指定創(chuàng)建代理對(duì)象/目標(biāo)對(duì)象實(shí)現(xiàn)的接口的類型)
動(dòng)態(tài)代理的別稱:JDK代理、接口代理
類圖:
Java動(dòng)態(tài)代理類位于java.lang.reflect包下
一般主要涉及到以下兩個(gè)類:
1、Interface InvocationHandler : 該接口中僅定義了一個(gè)方法public object invoke(Object obj,Method method, Object[] args) 在實(shí)際使用時(shí),第一個(gè)參數(shù)obj一般是指代理類,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)作被代理類使用(可使用被代理類的在接口中聲明過的方法)
動(dòng)態(tài)代的實(shí)現(xiàn)步驟:
創(chuàng)建一個(gè)實(shí)現(xiàn)接口InvocationHandler的類,它必須實(shí)現(xiàn)invoke方法
創(chuàng)建被代理的類以及接口
調(diào)用Proxy的靜態(tài)方法,創(chuàng)建一個(gè)代理類:newProxyInstance(ClassLoader loader,Class[]
通過代理調(diào)用方法
比如現(xiàn)在有一個(gè)汽車駕駛的方法:
public interface Moveable { void move(); }
現(xiàn)在有一輛汽車:
//實(shí)現(xiàn)Moveable 接口,并隨機(jī)暫停一段時(shí)間 import java.util.Random; public class Car implements Moveable{ @Override public void move() { try{ Thread.sleep(new Random().nextInt(1000)); System.out.println("汽車行駛中"); } catch (InterruptedException e) { e.printStackTrace(); } } }
時(shí)間代理類:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TimeHandler implements InvocationHandler{ public TimeHandler(Object target){ super(); this.target = target; } private Object target; /** * * @param proxy :被代理的對(duì)象 * @param method:被代理對(duì)象的方法 * @param args:方法的參數(shù) * @return * @throws Throwable * 返回值:Object 方法的返回值 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); System.out.println("汽車開始行使"); method.invoke(target); long endTime = System.currentTimeMillis(); System.out.println("汽車行駛結(jié)束,行駛的時(shí)間為:"+(endTime-startTime)+"毫秒"); return null; } }
測(cè)試類:
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args) { Car car = new Car(); InvocationHandler h = new TimeHandler(car); Class<?> cls = car.getClass(); /** * newProxyInstanced的參數(shù) * 分別是:類加載器、實(shí)現(xiàn)的接口、實(shí)現(xiàn)的處理器 */ Moveable m = (Moveable) Proxy.newProxyInstance(cls.getClassLoader(), cls.getInterfaces(),h); m.move(); } }
這樣的輸出結(jié)果是:
汽車開始行使
汽車行駛中
汽車行駛結(jié)束,行駛的時(shí)間為:137毫秒
//后面的時(shí)間是隨機(jī)產(chǎn)生的,每次都不一樣
注意:
JDK代理只能代理實(shí)現(xiàn)了接口的類,沒有實(shí)現(xiàn)接口的不能代理
以上就是JDK動(dòng)態(tài)代理,當(dāng)然還有cglib動(dòng)態(tài)代理:
cglib是針對(duì)類來實(shí)現(xiàn)代理的,cglib的原理是對(duì)指定的目標(biāo)類生成一個(gè)子類,并覆蓋其中方法實(shí)現(xiàn)增強(qiáng),但因?yàn)椴捎玫氖抢^承,所以不能對(duì)final修飾的類進(jìn)行代理,因?yàn)樾?yīng)學(xué)長(zhǎng)自己對(duì)這一塊也沒有完全掌握,這里就不多講解,大家可以參考其他博主的技術(shù)文章。
以上就是“Java代理模式實(shí)例代碼分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會(huì)為大家更新不同的知識(shí),如果還想學(xué)習(xí)更多的知識(shí),請(qǐng)關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。