代理模式(Proxy)-利用反射机制实现的动态代理

   Java深入到一定程度,就不可避免的碰到设计模式这一概念,了解设计模式,将使自己对java中的接口或抽象类应用有更深的理解.设计模式在java的中型系统中应用广泛,遵循一定的编程模式,才能使自己的代码便于理解,易于交流,Proxy(代理)模式是比较常用的一个模式.
       在应用中,有些对象有时候由于跨越网络或者其他的障碍,而不能够或者不想直接访问另一个对象,如果直接访问会给系统带来不必要的复杂性,这时候可以在客户程序和目标对象之间增加一层中间层,让代理对象来代替目标对象打点一切。
 
       Proxy 的使用场景:
       1.远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代表对象。这个不同的地址空间可以是在本机器中,也可是在另一台机器中。远程代理又叫做大使(Ambassador)。好处是系统可以将网络的细节隐藏起来,使得客户端不必考虑网络的存在。客户完全可以认为被代理的对象是局域的而不是远程的,而代理对象承担了大部份的网络通讯工作。由于客户可能没有意识到会启动一个耗费时间的远程调用,因此客户没有必要的思想准备。
       2.虚拟(Virtual)代理:根据需要创建一个资源消耗较大的对象,使得此对象只在需要时才会被真正创建。使用虚拟代理模式的好处就是代理对象可以在必要的时候才将被代理的对象加载;代理可以对加载的过程加以必要的优化。当一个模块的加载十分耗费资源的情况下,虚拟代理的好处就非常明显。
       3.Copy-on-Write代理:虚拟代理的一种。把复制(克隆)拖延到只有在客户端需要时,才真正采取行动。
       4.保护(Protect or Access)代理:控制对一个对象的访问,如果需要,可以给不同的用户提供不同级别的使用权限。保护代理的好处是它可以在运行时间对用户的有关权限进行检查,然后在核实后决定将调用传递给被代理的对象。
       5.Cache代理:为某一个目标操作的结果提供临时的存储空间,以便多个客户端可以共享这些结果。
       6.防火墙(Firewall)代理:保护目标,不让恶意用户接近。
       7.同步化(Synchronization)代理:使几个用户能够同时使用一个对象而没有冲突。
       8.智能引用(Smart Reference)代理:当一个对象被引用时,提供一些额外的操作,比如将对此对象调用的次数记录下来等。

       这里介绍的是如何利用反射机制实现动态代理:
       最常见的情况是:但一个应用已经开发结束后,我们需要对针对一些对象的操作记录日志或者做一些额外的工作;在这种情况下我们如果为每一个对象设计一个代理类的话显然会增加很多工作量,如果采用反射机制的话就可以轻松的解决这个问题。

       在此写了4个java类来描述说明Proxy设计模式的动态代理实现方式;

      1、 ReflectProxy.java      动态代理类
      2、 IHelloWorld.java       HelloWorld接口
      3、 HelloWorld.java        HelloWorld实现类
      4、 ReflectProxyText.java  带有main方法的测试类

===============   1、 ReflectProxy.java
package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//通过实现InvocationHandler接口的invoke方法 促使被代理对象的方法别调用时都会出发invoke方法
public class ReflectProxy implements InvocationHandler {

  // 被代理的对象
  private Object proxyObject;

  public ReflectProxy(Object proxyObject) {
    this.proxyObject = proxyObject;
  }

  // 通过工厂模式生成一个代理对象
  public static Object factory(Object proxyObject) {
    Class cls = proxyObject.getClass();
    return Proxy.newProxyInstance(cls.getClassLoader(),
        cls.getInterfaces(), new ReflectProxy(proxyObject));

  }

  //InvocationHandler 接口中的方法
  public Object invoke(Object proxy, Method method, Object[] args)
      throws Throwable {
   
    //在调用被代理类的实际方法前的操作
    doBeforeCalling(method);

    //输出被代理类的实际方法中的参数
    if (args != null) {
      for (int i = 0; i < args.length; i++) {
        System.out.println("args[" + i + "]=" + args[i] + "");
      }
    }
   
    //调用被代理类的实际方法
    Object o = method.invoke(proxyObject, args);

    //在调用被代理类的实际方法后的操作
    doAfterCalling(method);

    return o;
  }
 
  //在调用被代理类的实际方法前的操作
  private void doBeforeCalling(Method method){
    System.out.println("before calling [" + method + "]");
  }

  //在调用被代理类的实际方法后的操作
  private void doAfterCalling(Method method){
    System.out.println("after calling [" + method + "]");
  }

}
===============   1 end

 

===============   2、 IHelloWorld.java
package proxy;

public interface IHelloWorld {

  public void sayHello();
  public void sayBye();
  public void saySomething(String msg);
 
}
===============   2 end

 

===============   3、 HelloWorld.java
package proxy;

public class HelloWorld implements IHelloWorld {

  public void sayBye() {
    System.out.println("Hello World!");
  }

  public void sayHello() {
    System.out.println("Bye!");
  }

  public void saySomething(String msg) {
    System.out.println(msg);
  }
}
===============   3 end

 

===============   4、 ReflectProxyText.java
package proxy;

import java.util.ArrayList;
import java.util.List;

public class ReflectProxyText {

  public static void main(String[] args) {
    try {
      //代理List接口对象
      Object obj = ReflectProxy.factory(new ArrayList<Object>(0));
      List list = (List)obj;
      list.add("A");
      list.add("B");
     
      //代理IHelloWorld接口对象
      obj = ReflectProxy.factory(new HelloWorld());
      IHelloWorld helloWorld = (IHelloWorld)obj;
      helloWorld.sayHello();
      helloWorld.saySomething("How is everything!");
      helloWorld.sayBye();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
===============   4 end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值