首先認(rèn)識(shí)一下所謂的代理: 從主方角度:代理就是找人幫忙自己完成自己事情,那么這就需要代理方有絕對(duì)的操作執(zhí)行權(quán),對(duì)應(yīng)到代碼中就是,代理方可以完成主方可以完成的所有操作。 從客戶角度:代理就是對(duì)于自己達(dá)到目的而言最簡(jiǎn)單、完善的中介。對(duì)應(yīng)到代碼中就是,當(dāng)代理接收到用戶的請(qǐng)求時(shí),可以在執(zhí)行用戶的請(qǐng)求前后加一些額外的操作,使得代碼更加的強(qiáng)壯、完善。 從代理角度而言:自己可以保證主方和客戶方的權(quán)益問(wèn)題,一方面達(dá)到了客戶的要求,另一方面也保護(hù)了主方的一些隱私問(wèn)題。對(duì)應(yīng)到代碼就是完善了對(duì)于后臺(tái)數(shù)據(jù)的保護(hù)。
在java中代理可以分為靜態(tài)代理和動(dòng)態(tài)代理。
靜態(tài)代理,顧名思義,一個(gè)代理完成一個(gè)真實(shí)對(duì)象的代理,那么我們的代碼量也會(huì)成倍的增加。對(duì)于具有相同功能的代理無(wú)法進(jìn)行合并。 下面通過(guò)一個(gè)例子來(lái)了解一下: 接口類的定義: package dong.application.staticProxy; public interface SubClass { public abstract void request(); } 主方的定義(即主要操作的實(shí)際擁有者): package dong.application.staticProxy; public class RealSubClass implements SubClass { @Override public void request() { System.out.println("i am RealSubClass"); } } 代理方的操作(在完成主要的操作時(shí)可以增加一些額外的內(nèi)容): package dong.application.staticProxy; public class ProxySubClass implements SubClass { private RealSubClass realSubClass; public ProxySubClass() { if(realSubClass == null) { realSubClass = new RealSubClass(); } } @Override public void request() { System.out.println("before realSubClass Invoked"); realSubClass.request(); System.out.println("after realSubClass Invoked"); } } 客戶端的操作: package dong.application.staticProxy; publicclass Client { publicstaticvoid main(String[] args) { ProxySubClass proxy = new ProxySubClass(); proxy.request(); } } 下面分析一下其執(zhí)行過(guò)程: 當(dāng)客戶向代理發(fā)送請(qǐng)求的時(shí)候,代理可以在執(zhí)行代理內(nèi)容前,做一些額外的操作,然后執(zhí)行代理操作,當(dāng)執(zhí)行完代理之后,還可以加一些額外的操作。 通過(guò)上述的總結(jié),我們可以了解到:一個(gè)主方可以找多個(gè)代理,這樣就實(shí)現(xiàn)了不同代理完成不同方向的功能。它與繼承的區(qū)別繼承是擁有主方所有的決定權(quán)和操作權(quán),給用戶的感覺(jué)就是它比主方擁有更多的操作。那么用戶就可以進(jìn)行主方的直接操作;然而代理操作時(shí),只是在代理方完成主方的某些操作。對(duì)用戶而言就是不可跨越的。
動(dòng)態(tài)代理: Java中的動(dòng)態(tài)代理主要是通過(guò)反射實(shí)現(xiàn)的: 實(shí)現(xiàn)動(dòng)態(tài)代理的兩個(gè)關(guān)鍵類: java.lang.reflect.Proxy。這個(gè)類主要是完成一個(gè)動(dòng)態(tài)代理實(shí)例的生成,即客戶點(diǎn)名要某個(gè)代理,下面看一下類簡(jiǎn)介: 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. 也就是說(shuō)當(dāng)你通過(guò)一些靜態(tài)方法生成的代理類,這些類的父類都是Proxy。 To create a proxy for some interface Foo: InvocationHandler handler = new MyInvocationHandler(...); Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class }); Foo f = (Foo) proxyClass. getConstructor(new Class[] { InvocationHandler.class }). newInstance(new Object[] { handler }); or more simply: Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(), new Class[] { Foo.class },handler); 這個(gè)類中的public static newProxyInstance( loader, <?>[] interfaces, h) throws 可以完成一個(gè)代理的動(dòng)態(tài)生成。 該函數(shù)的簡(jiǎn)介及其使用: Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler. This method is equivalent to: Proxy.getProxyClass(loader, interfaces). getConstructor(new Class[] { InvocationHandler.class }).newInstance(new Object[] { handler }); 其參數(shù)及其含義如下: loader - the class loader to define the proxy class interfaces - the list of interfaces for the proxy class to implement h - the invocation handler to dispatch method invocations to 那么圍繞著一個(gè)動(dòng)態(tài)代理類的生成,引出另一個(gè)重要的類:java.lang.reflect Interface InvocationHandler。這個(gè)接口是用戶所要請(qǐng)求的操作實(shí)際執(zhí)行者,就相當(dāng)于上述靜態(tài)代理中的request方法的功能。簡(jiǎn)單看一下類簡(jiǎn)介: InvocationHandler is the interface implemented by the invocation handler of a proxy instance. 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. 下面我們就看一下它的invoke方法: Object invoke(Object proxy, Method method, Object[] args) throws Throwable 函數(shù)功能:Processes a method invocation on a proxy instance and returns the result. This method will be invoked on an invocation handler when a method is invoked on a proxy instance that it is associated with. 其參數(shù)及其含義: proxy - the proxy instance that the method was invoked on【所要執(zhí)行的方法所在的類】 method - the Method instance corresponding to the interface method invoked on the proxy instance. The declaring class of the Method object will be the interface that the method was declared in, which may be a superinterface of the proxy interface that the proxy class inherits the method through.【所要執(zhí)行的方法】 args - an array of objects containing the values of the arguments passed in the method invocation on the proxy instance, or null if interface method takes no arguments. Arguments of primitive types are wrapped in instances of the appropriate primitive wrapper class, such as java.lang.Integer or java.lang.Boolean.【執(zhí)行該方法所需要的參數(shù)】 返回值的含義就簡(jiǎn)單明了了,也就是用戶所需求的結(jié)果。
下面通過(guò)一個(gè)實(shí)力來(lái)了解學(xué)習(xí)動(dòng)態(tài)代理: 主方接口: package dong.applicationDynamicProxy; public interface SubClass { public abstract void request(); } 主方的實(shí)現(xiàn)類: package dong.applicationDynamicProxy; public class RealSubClass implements SubClass { @Override public void request() { System.out.println("real class method is invoking"); } } 動(dòng)態(tài)代理的執(zhí)行類,即handler package dong.applicationDynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxyInvocationHandler implements InvocationHandler { private Object obj; public DynamicProxyInvocationHandler(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before real class invoke"); System.out.println(proxy.getClass().getName()); Object result = method.invoke(obj,args); System.out.println("after real class invoke"); System.out.println(result); return result; } } 客戶端的執(zhí)行(包含動(dòng)態(tài)代理類的生成) package dong.applicationDynamicProxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class DynamicProxy { public static void main(String[] args) { RealSubClass realClass = new RealSubClass(); DynamicProxyInvocationHandler dpih = new DynamicProxyInvocationHandler(realClass); // ClassLoader loder = dpih.getClass().getClassLoader(); SubClass subClass = (SubClass) factory(realClass.getClass().getClassLoader(), RealSubClass.class.getInterfaces(), dpih); subClass.request(); } //生成動(dòng)態(tài)代理的實(shí)例 public static Object factory(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) { return Proxy.newProxyInstance(loader, interfaces, h); } } |
|