java 动态代理

java 有一个动态代理的功能,它允许在 java 运行过程中,基于一个类动态产生另一个 java 类,此类是代理类,任何对前者里面的某个方法的调用可以通过代理类的调用来完成,这就是“代理”的作用。举例如下:

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

interface MyInteger
{
	public void say();
}
class MyInterImpl implements MyInteger
{
	private int _value;
	public MyInterImpl(int i ) {
		_value = i;
	}
	@Override
	public void say() {
		System.out.println("_value : " + _value);
	}
	
}

public class ProxyTest
{  
   public static void main(String[] args)
   {  
      MyInteger[] elements = new MyInteger[10];

      for (int i = 0; i < elements.length; i++)
      {
    	 MyInterImpl value = new MyInterImpl(i + 1);
    
         Class[] interfaces = value.getClass().getInterfaces();
         InvocationHandler handler = new TraceHandler(value);
         try{
         elements[i] = (MyInteger)Proxy.newProxyInstance(MyInteger.class.getClassLoader(),
            interfaces, handler);
         }
         catch(Exception ex)
         {
        	 ex.printStackTrace();
        	 throw ex;
         }
      }

      for(MyInteger o : elements)
      {
    	  o.say();  //任何在 MyInteger 上的调用均会被先定向到代理类的 invoke 方法上
      }
      
   }
}

/**
   An invocation handler that prints out the method name
   and parameters, then invokes the original method
*/
class TraceHandler implements InvocationHandler
{ 
   /**
      Constructs a TraceHandler
      @param t the implicit parameter of the method call
   */
   public TraceHandler(Object t)
   {  
      target = t;
   }

   public Object invoke(Object proxy, Method m, Object[] args) throws Throwable//此方法在代理类中
   {  														   //的方法被调用时均会被调用
      // print implicit argument
      System.out.print(target);
      // print method name
      System.out.print("." + m.getName() + "(");
      // print explicit arguments
      if (args != null)
      {
         for (int i = 0; i < args.length; i++)
         {  
            System.out.print(args[i]);
            if (i < args.length - 1)
               System.out.print(", ");
         }
      }
      System.out.println(")");
        //调用实际的方法
      return m.invoke(target, args);
   }

   private Object target;
}

这是个非常有用的特性,我们可以利用这个特性在运行期动态替换掉某种具体的实现,或者针对于某种接口产生具体的实现。更进一步,它还允许我们在某一环境下使用一种实现,另一环境下使用另一实现,如对测试环境和生产环境的区分有不同的程序逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值