动态代理模式newProxyInstance及invoke方法参数详解
動(dòng)態(tài)代理概述:
Java提供的動(dòng)態(tài)代理類(lèi)Proxy:
Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods. 代理類(lèi)Proxy提供靜態(tài)方法用于創(chuàng)建動(dòng)態(tài)代理子類(lèi)和對(duì)象。它也是所有通過(guò)這些靜態(tài)方法所創(chuàng)建的動(dòng)態(tài)代理子類(lèi)的父類(lèi)。其中一個(gè)最常用的靜態(tài)方法就是:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler handler) Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler. 返回一個(gè)實(shí)現(xiàn)了所有指定接口的代理子類(lèi)對(duì)象,該對(duì)象將方法調(diào)用分派給指定的調(diào)用處理器。
ClassLoader :被代理類(lèi)的類(lèi)加載器,方法內(nèi)部會(huì)調(diào)用這個(gè)類(lèi)加載器來(lái)獲取繼承Proxy類(lèi)的子類(lèi)字節(jié)碼文件對(duì)象Class,加載的同時(shí)該子類(lèi)也實(shí)現(xiàn)所有指定的接口。
Class<?>[] interfaces: 被代理類(lèi) 的所有實(shí)現(xiàn)接口的Class對(duì)象,在方法內(nèi)部會(huì)克隆一份加載進(jìn)Proxy字節(jié)碼對(duì)象中。
表示實(shí)現(xiàn)Proxy類(lèi)實(shí)現(xiàn)所有指定接口。
InvocationHandler接口:(調(diào)用處理器)
InvocationHandler is the interface implemented by the invocation handler of a proxy instance. 調(diào)用處理器是一個(gè)通過(guò) 代理對(duì)象的調(diào)用處理器(Handler實(shí)現(xiàn)類(lèi)中的invoke) 來(lái)實(shí)現(xiàn)的接口 Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler. 每一個(gè)代理對(duì)象都有相關(guān)聯(lián)的調(diào)用處理器。 當(dāng)一個(gè)方法伴隨所屬代理對(duì)象被調(diào)用,這個(gè)方法調(diào)用就會(huì)被編碼轉(zhuǎn)移為調(diào)用處理器中的相應(yīng)擴(kuò)展方法調(diào)用。? 總的來(lái)講,每一個(gè)proxy代理對(duì)象都有一個(gè)實(shí)現(xiàn)InvocationHandler接口的實(shí)現(xiàn)類(lèi)Handler,這個(gè)實(shí)現(xiàn)類(lèi)中的invoke方法就是proxy代理對(duì)象的實(shí)際調(diào)用處理器,在這個(gè)invoke方法體中,有所有 被代理對(duì)象 的方法邏輯實(shí)現(xiàn)和擴(kuò)展。
? 每當(dāng)代理對(duì)象proxy被反射機(jī)制用于調(diào)用其方法時(shí),這個(gè)方法調(diào)用就自動(dòng)轉(zhuǎn)移為Handler類(lèi)里invoke方法體中的對(duì)應(yīng)擴(kuò)展方法調(diào)用。
InvocationHandler這個(gè)接口的唯一一個(gè)方法 invoke 方法:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable proxy:代理對(duì)象,只是反射機(jī)制調(diào)用方法的需要 method: proxy被反射機(jī)制用于調(diào)用的方法對(duì)象 args:調(diào)用方法的參數(shù)列表動(dòng)態(tài)代理實(shí)現(xiàn):
這里面首先想要做到動(dòng)態(tài)代理,必須先實(shí)現(xiàn)這個(gè)InvocationHandler接口,然后我們主要看getProxy方法,參數(shù)是需要被代理的對(duì)象Singer
? 方法里面有一個(gè)Proxy類(lèi),這個(gè)Proxy類(lèi)提供了很多方法,這里我們用的是newProxyInstance方法,它有三個(gè)參數(shù),第一個(gè)是被代理類(lèi)的類(lèi)構(gòu)造器,第二個(gè)指的是被代理類(lèi)的接口,也就是Singer的接口,第三個(gè)是實(shí)現(xiàn)這個(gè)代理過(guò)程的類(lèi),就是本類(lèi)。具體的來(lái)說(shuō),這個(gè)方法執(zhí)行了下面三步:
? 1.用ClassLoader加載器生成一個(gè)實(shí)現(xiàn)了參數(shù)interfaces里所有接口且繼承了Proxy的代理類(lèi)的字節(jié)碼對(duì)象。
? 2.使用Proxy的構(gòu)造函數(shù) Proxy(InvocationHandler h)來(lái)創(chuàng)造一個(gè)代理類(lèi)的實(shí)例,將我們自定義的InvocationHandler子類(lèi)傳入。
? 3.返回這個(gè)代理類(lèi)實(shí)例對(duì)象,因?yàn)槲覀儤?gòu)造的代理類(lèi)實(shí)現(xiàn)了interfaces(也就是我們程序中傳入的Singer.class.getInterfaces())里的所有接口,因此返回的代理類(lèi)可以強(qiáng)轉(zhuǎn)成Star類(lèi)型來(lái)調(diào)用接口中定義的方法。
而在調(diào)用每個(gè)代理類(lèi)每個(gè)方法的時(shí)候,都用反射去調(diào)InvocationHandler實(shí)現(xiàn)類(lèi)的invoke方法(也就是我們自定義的AutoProxy重寫(xiě)的invoke方法),用參數(shù)傳遞了代理類(lèi)實(shí)例、接口方法、調(diào)用參數(shù)列表,這樣我們?cè)谥貙?xiě)的invoke方法中就可以實(shí)現(xiàn)對(duì)所有方法的統(tǒng)一包裝了。
總結(jié)
以上是生活随笔為你收集整理的动态代理模式newProxyInstance及invoke方法参数详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: html全屏背景视频特效,HTML5全屏
- 下一篇: 寒假回家只带一本书:《编程之美》——华中