分享

java SE静态代理和动态代理

 昵称9918558 2012-05-08

首先认识一下所谓的代理:

从主方角度:代理就是找人帮忙自己完成自己事情,那么这就需要代理方有绝对的操作执行权,对应到代码中就是,代理方可以完成主方可以完成的所有操作。

从客户角度:代理就是对于自己达到目的而言最简单、完善的中介。对应到代码中就是,当代理接收到用户的请求时,可以在执行用户的请求前后加一些额外的操作,使得代码更加的强壮、完善。

从代理角度而言:自己可以保证主方和客户方的权益问题,一方面达到了客户的要求,另一方面也保护了主方的一些隐私问题。对应到代码就是完善了对于后台数据的保护。

 

 

java中代理可以分为静态代理和动态代理。

 

静态代理,顾名思义,一个代理完成一个真实对象的代理,那么我们的代码量也会成倍的增加。对于具有相同功能的代理无法进行合并。

下面通过一个例子来了解一下:

接口类的定义:

package dong.application.staticProxy;

public interface SubClass

{

       public abstract void request();

}

主方的定义(即主要操作的实际拥有者):

package dong.application.staticProxy;

public class RealSubClass implements SubClass

{

       @Override

       public void request()

       {

              System.out.println("i am RealSubClass");

       }

}

代理方的操作(在完成主要的操作时可以增加一些额外的内容):

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();

       }

}

下面分析一下其执行过程:

当客户向代理发送请求的时候,代理可以在执行代理内容前,做一些额外的操作,然后执行代理操作,当执行完代理之后,还可以加一些额外的操作。

通过上述的总结,我们可以了解到:一个主方可以找多个代理,这样就实现了不同代理完成不同方向的功能。它与继承的区别继承是拥有主方所有的决定权和操作权,给用户的感觉就是它比主方拥有更多的操作。那么用户就可以进行主方的直接操作;然而代理操作时,只是在代理方完成主方的某些操作。对用户而言就是不可跨越的。

 

 

动态代理:

Java中的动态代理主要是通过反射实现的:

实现动态代理的两个关键类:

java.lang.reflect.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也就是说当你通过一些静态方法生成的代理类,这些类的父类都是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);

这个类中的public static newProxyInstance( loader,                                      <?>[] interfaces, h) throws 可以完成一个代理的动态生成。

该函数的简介及其使用:

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 });

其参数及其含义如下:

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

那么围绕着一个动态代理类的生成,引出另一个重要的类:java.lang.reflect Interface InvocationHandler。这个接口是用户所要请求的操作实际执行者,就相当于上述静态代理中的request方法的功能。简单看一下类简介:

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

函数功能: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.

其参数及其含义:

proxy - the proxy instance that the method was invoked on【所要执行的方法所在的类】

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.【所要执行的方法】

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.【执行该方法所需要的参数】

返回值的含义就简单明了了,也就是用户所需求的结果。

 

 

下面通过一个实力来了解学习动态代理:

主方接口:

package dong.applicationDynamicProxy;

public interface SubClass

{

       public abstract void request();

}

主方的实现类:

package dong.applicationDynamicProxy;

public class RealSubClass implements SubClass

{

       @Override

       public void request()

       {

              System.out.println("real class method is invoking");

       }

}

动态代理的执行类,即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;

       }

}

客户端的执行(包含动态代理类的生成)

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();

       }

       //生成动态代理的实例

       public static Object factory(ClassLoader loader, Class<?>[] interfaces,

                     InvocationHandler h)

       {

              return Proxy.newProxyInstance(loader, interfaces, h);

       }

}

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多