您的位置:首页 > 编程语言 > Java开发

Java中的代理模式----静态代理和动态代理

2013-08-20 22:32 253 查看
代理模式的英文叫做Proxy或Surrogate,所谓代理,就是一个人或者一个机构代表一个机构采取行动。

为其他对象提供一种代理以控制这个对象的访问。

在一些情况下,一个客户不想或者不能直接引用一个对象,而代理对象可以在客户端和目标对象之间起起到中介作用。

 

代理模式一般涉及到的角色有:

  抽象角色:声明真实对象和代理对象的共同接口;

  代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装;

  真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。

       客户角色:客户角色访问代理角色,最终得到真实角色。

 

 

===================静态代理===================

静态代理示例代码:

/**
 *
  * 创建接口或抽象类(抽象角色)
 *
 */
public interface BookManager {

    [b]public void [/b]add(String book);
}
 

/**
 * 创建实现接口的真实角色
 *
 */
publicclass BookManagerImplimplements BookManager
{
 

    publicvoid add(String book) {
       System.out.println(String.format("---------%s---------",
book));
    }
}
 

/**
 * 创建实现接口的代理角色(代理角色内部,要有真实角色的引用)
 *
 */
publicclass BookMimplements BookManager {
 

    private BookManagerbookManager=new
BookManagerImpl();
 

    publicvoid add(String book) {
       System.out.println("------调用前-------");   
       bookManager.add(book);
       System.out.println("------调用后-------");

    }
}
 

/**
 *
客户角色
 *
 */
publicclass Test {
   
    publicstaticvoid main(String[] args) {
       BookManager bm=new BookM();
       bm.add("编程思想");
    }
}
 

输出结果:

------调用前-------

---------编程思想---------

------调用后-------

 

 
如上代码,BookM提供了BookManagerImpl类的引用,以便可以在代理角色中访问真实角色。

在客户想得到真实对象,想在真实对象的里面做其他操作,却又不愿意修改真实对象的时候,代理模式就可以轻松完成。

 

 

 

 

===================动态代理===================

Java动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类(接口算作特殊类):

(1)Interface InvocationHandler:该接口中仅定义了一个方法

public object invoke(Object obj,Method method, Object[] args)

在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法, 这个抽象方法在代理类中动态实现。

(2)Proxy:该类即为动态代理类,作用类似于上例中的BookM,其中主要包含以下内容:

protected Proxy(InvocationHandler h):构造函数,用于给内部的h赋值;

 

 

 
动态代理示例代码:

/**
 *
创建接口(抽象角色)
 *
 */
publicinterface BookManager {
 
    publicvoid add(String book);
}
 

 

/**
 * 创建实现接口的真实角色
 *
 */
publicclass BookManagerImplimplements BookManager
{
 

    publicvoid add(String book) {
       System.out.println(String.format("---------%s---------",
book));
    }
}
 
 
 
/**
 * 创建代理处理器,该类实现InvocationHandler。
 * 该类有一个Object类型的内部属性,使用时,可以通过构造函数进行赋值,
 * 也可以在创建代理时,给一个代理类的引用.(本例为后者)
 * 另外,该类还实现了invoke方法,该方法中的method.invoke(targerObj,args);
 * 实际上就是调用执行被代理对象(真实角色)中的方法.
 * args为执行被代理对象(真实角色)所需要的参数.
 * 通过此类,可以在调用之前或之后,做其他一些操作
 */
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
publicclass HandlerTestimplements InvocationHandler
{
 
    private ObjecttargetObj;
    //创建一个代理类
    public Object createProxy(Object targetObj){
       this.targetObj=targetObj;
       return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(),
              targetObj.getClass().getInterfaces(),this);
      
    }
   
    public Object invoke(Object proxy, Method method, Object[] args)
           throws Throwable {
       System.out.println("-----调用前--方法名称:"+method.getName());
       //执行被代理类(真实对象)的方法
       Object obj=method.invoke(targetObj, args);
       System.out.println("-----调用前-----");
      
       return obj;
    }

}
 

/**
 *
客户对象
 * @author PF
 *
 */
publicclass Test {
 
    publicstaticvoid main(String[] args) {
      
       HandlerTest ht=new HandlerTest();
      
       BookManager bm= (BookManager)ht.createProxy(new BookManagerImpl());
       bm.add("动态代理");
    }
 
}

 

执行结果:

-----调用前--方法名称:add
-------动态代理--------
-----调用前-----

 

 

如上代码,动态代理中,创建代理类(代理角色),只需要一个被代理类(真实角色)的引用即可.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: