Java代理相關(guān)主要知識(shí)如下:
(1)利用代理可以在運(yùn)行時(shí)創(chuàng)建一個(gè)實(shí)現(xiàn)了一組給定接口的新類限府。
這種功能只有在編譯時(shí)無法確定需要實(shí)現(xiàn)哪個(gè)接口時(shí)才有必要使用堤舒。
(2)假設(shè)有一個(gè)表示接口的Class對象,它的確切類型在編譯時(shí)無法知道。
要想構(gòu)建一個(gè)實(shí)現(xiàn)接口的類,就需要使用NewInstance方法或反射找出這個(gè)類的構(gòu)造器。
但是不能實(shí)例化一個(gè)接口,需要在程序處于運(yùn)行狀態(tài)時(shí)定義一個(gè)新類。
(3)為解決這個(gè)問題捕透,有些程序?qū)?huì)生成代碼,將這些代碼放置在一個(gè)文件中碴萧,使用編譯器乙嘀,然后再加載結(jié)果類文件。
【Java免費(fèi)學(xué)習(xí)資料分享微信:tangniu520666破喻,備注“4”虎谢,需要的可以加我哦】
針對上述繁瑣的過程,可以使用代理機(jī)制曹质。
代理機(jī)制是一種很好的解決方案婴噩,代理類可以再運(yùn)行時(shí)創(chuàng)建全新的類,這樣的代理類能夠?qū)崿F(xiàn)指定的接口羽德。
但是几莽,這樣做的速度會(huì)比較的慢,且需要將編譯器與程序放在一起玩般。
(4)它具有下列的方法:
(a)指定接口所需要的全部方法银觅。
(b)Object類中的全部方法礼饱,例如toString坏为、equals等。
(5)但是不能在運(yùn)行時(shí)定義這些方法镊绪,需要提供一個(gè)調(diào)用處理器(Invocationhandler)匀伏。
調(diào)用處理器是實(shí)現(xiàn)了Invocationhandler接口的類對象。
這個(gè)接口只有一個(gè)方法:
Object invoke(Object proxy, Method method, Object[] args)
(6)無論何時(shí)調(diào)用代理對象方法蝴韭,調(diào)用處理器的invoke方法都會(huì)被調(diào)用够颠,并向其傳遞Method對象和原始的調(diào)用參數(shù)。
(7)要?jiǎng)?chuàng)建以一個(gè)代理對象榄鉴,需使用Proxy類的NewProxyInstance方法履磨。方法的三個(gè)參數(shù)為:
(a)一個(gè)類加載器蛉抓。
(b)一個(gè)Class對象數(shù)組,每個(gè)元素都是需要實(shí)現(xiàn)的接口剃诅。
(c)一個(gè)調(diào)用處理器巷送。
(8)代理類的特性:
代理類實(shí)在程序運(yùn)行過程中創(chuàng)建的,一旦被創(chuàng)建矛辕,就變成常規(guī)類了笑跛。
所有的代理類都擴(kuò)展于Proxy類。一個(gè)代理類只有一個(gè)實(shí)例域——調(diào)用處理器聊品。它定義在Proxy超類中飞蹂,
為了履行代理對象的職責(zé),所需要的任何附加數(shù)據(jù)都必須存儲(chǔ)在調(diào)用處理器中翻屈。
所有代理類都覆蓋了Object類中的toString陈哑、equals和hashCode方法。
(9)對于特定的類加載器和預(yù)設(shè)的一組接口來說伸眶,只能有一個(gè)代理類芥颈。
如果使用同一個(gè)類加載器的接口數(shù)組調(diào)用兩次newProxyInstance方法,那么只能得到同一個(gè)類的兩個(gè)對象赚抡,
也可以使用getProxyClass方法獲得這個(gè)類:
Class proxyClass = Proxy.getProxyClass(null, interfaces);
(10)代理類一定是public和final爬坑。
如果代理類實(shí)現(xiàn)的所有接口都是public,代理類就不屬于某個(gè)特定的包;
否則涂臣,所有非公有的接口都必須屬于同一個(gè)包盾计,同時(shí),代理類也屬于這個(gè)包赁遗。
可以通過調(diào)用Proxy類中的isProxyClass方法檢測一個(gè)特定的Class對象是否代表一個(gè)代理類署辉。