论坛首页 入门技术论坛

代理模式(Proxy)

浏览 7088 次
该帖已经被评为新手帖
作者 正文
   发表时间:2008-05-09  
代理模式,个人认为就是把你要使用的一个对象尽享封装,包装。编程原对象的一个副本,在使用的时候直接使用他这个副本就可以了!他的作用用专业点的语言描述就是为其他的对象提供一个代理方便控制这个对象。当我们不能直接调用另外一个对象,但是又不得不用这个对象的某些功能,此时代理对象就能起到链接客户和目标对象的一个代理.
代理模式一般涉及到三个角色,分别为:
1. 抽象角色:他提供真实对象和代理对象的共同接口。
2. 代理角色:通俗地说,代理角色是对原对象(目标对象)进行包装,他有着和原对象相同的接口,并且可以执行真实对象的操作。
3. 真实角色:即目标对象,最终我们需要对他的操作。
代理模式分为两种,一 静态代理,二 动态代理。

接下来我们介绍一下两种代理模式:

一 静态代理
   静态代理即 代理对象和被代理对象在代理之前已经确定好了。他们一起实现相同的接口或者是继承相同的抽象类。例如:
//定义抽象角色
public abstract class AbsRole{
  abstract public void work();
}


//定义真实角色
public class RealRole extends AbsRole{
  public RealRole(){ }

  public void work(){
    System.out.println("调用真实角色中函数!");
  }
}

//代理角色
public class ProxyRole extends AbsRole{
  public RealRole real ;
  
  public ProxyRole(){
  }

  public void work(){
    this.beforeMethod();
    if(real == null){
      real = new RealRole();
    }
    real.work();
    this.endMethod();
  }

  public void beforeMethod(){
    System.out.println("代理前执行函数->beforeMethod()");
  }
  
  public void endMethod(){
    System.out.println("代理时候后执行函数->endMethod()");
  }
}


各种角色我们都已经定义好了,我们开始测试一下。

public class Main(){
  public static void main(String[] args){
    AbsRole ar = new ProxyRole();
    ar.work();
  }
}


二 动态代理
  顾名思义,就是不知道到底那个类需要做代理,在使用的时候,更具情况临时决定。
   java动态代理主要是使用java.lang.reflect包中的两个类。
1. interface InvocationHandler: 他中定义了一个方法
  public Object invoke(Object obj,Method method,Object[] obs)

  其中第一个参数 obj 指的是代理类,method是被代理的方法,obs是指被代理的方法的参数组。此方法由代理类来实现。
2. Proxy:该类为动态代理类,主要包括以下内容:

  protected Proxy(InvocationHandler h);

  static Class getProxyClass(ClassLoader loader,Class[] interfaces);

  static Object newProxyInstance(ClassLoader loader,Class[]interfaces,InvocationHandler h);


动态代理其实是在运行时生成class,所以,我们必须提供一组interface,然后告诉他class已经实现了这些interface,而且在生成Proxy的时候,必须给他提供一个handler,让他来接管实际的工作。
现在我们把静态代理的例子修改一下:
//定义抽象角色;
public interface AbsRole{
  public void work();
}


接下来定义真实角色;
public class RealRole implements AbsRole{
  public RealRole(){};
  
  public void work(){
    System.out.println("调用真实角色方法:RealRole.work()");
  }
}

然后书写动态代理编码
public class DynamicProxyRole implements InvocationHandler{
  private Object sub;
  
  public DynamicProxyRole(){}

  public DynamicProxyRole(Object ob){
    this.sub = ob;
  }

  public Object invoke(Object proxy, Method method, Object[] obs) throws Throwable{
    method.invke(sub,obs);
    return null;
  }
}

代理类已经书写完毕,看看是否能正常运行。
public class Main{
  public static void main(String[] args){
    RealRole  rr  = new RealRole();
    InvocationHandler dynamicProxy = new DynamicProxyRole(rr);
    Class<?> cls = rr.getClass();
    
    AbsRole r = (AbsRole)Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),DynamicProxyRole);
    r.work();
  }
}



调试成功,动态代理功能完成。

通过静态代理和动态代理学习,我们小结一下:
静态代理需要事先确定代理对象和被代理对象,他们要一起继承或者是实现相同的抽象类。动态代理可以在使用的时候传入真实对象,得到代理。动态代理还是主要依靠java本身的语言特性,实现代理,更加方便
   发表时间:2008-05-13  
从上面的例子,没看出代理的真实用途
0 请登录后投票
   发表时间:2008-05-13  
估计又要被评新手帖了
0 请登录后投票
   发表时间:2008-05-16  
我认为写的还是不错的。

要理解Spring的AOP,必须要先理解什么是动态代理。

个人认为Spring的AOP是建立在IOC基础之上的动态代理模式。

请各位大人批评指正,小弟是新手。

PS:貌似Spring的AOP很少应用到
0 请登录后投票
   发表时间:2008-05-18  
lz 是从代码事件的角度在描述代理 很实用

但其实说到代理 更多的是从设计模式的角度  那是一中思路
当用到某个资源的时候 就要先得到资源,但未必就马上要用 那么这个时候我们可以得到这个资源的代理 因为直接的得到或访问资源可能是很浪费时间的 但得到代理是很快速因为他并没有真正去调用资源 只有在我们真正实用的时候 才通过代理去调用真正的资源(但最后还是要去访问真正的资源,所以性能开销是一顶的)
具体的例子 就是spring的lazyinit;ejb的home和remote接口的方式
0 请登录后投票
   发表时间:2008-05-18  
我现在的项目中有一个字典.字典维护了很多的栏目.在删除字典中某一个栏目的时候,我需要先判断这个栏目下是否有文章,没文章才可以删除他.有文章是不可以删除的.在这里可以使用代理模式吗?
0 请登录后投票
   发表时间:2008-05-20  
不知道最后MAIN类Class<?> cls = rs.getClass();中RS是怎么来的
0 请登录后投票
   发表时间:2008-05-20  
静态代理怎么和Decorator模式差不多
0 请登录后投票
   发表时间:2008-05-20  
weijiang8410 写道
不知道最后MAIN类Class<?> cls = rs.getClass();中RS是怎么来的

不好意思,自己先是在txt里面写好,然后在工具中调试,调试的时候,做了点改动,忘记修改txt中的内容,现在更改过来。谢谢!
   我也是新手。最经在写个小框架的时候才开始关注这方面。大家一起讨论!
0 请登录后投票
   发表时间:2008-12-03  
学习了,不过好像还不是太清楚
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics