`
Arron.li
  • 浏览: 136529 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

java反射机制与动态代理

    博客分类:
  • Java
阅读更多

1 java反射机制:运行时的类信息

Class类与java.lang.reflect类库一起对反射概念进行了支持,该类库包含了Field,Method以及Constructor类。这些类型的对象是由JVM在运行时创建的,用以表示未知类里对应的成员。这样就可以使用Constructor创建新的对象,用get()与set()方法读取与修改与Field对象相关的字段,用invoke()方法调用与Method对象相关的方法等等。

 

2 动态代理:

代理模式:为了提供额外的或不同的操作,而插入的用来代替“实际”对象。这些操作通常涉及与“实际”对象的通讯,因此代理通常充当着中间人的角色。

动态代理:所有的调用都会被重定向到单一的调用处理器上,他的工作是揭示调用的类型并确定相应的对策。

java反射机制实现动态代理的源码:

interface Interface {
  void doSomething();
  void somethingElse(String arg);
}

class RealObject implements Interface {
  public void doSomething() { print("doSomething"); }
  public void somethingElse(String arg) {
    print("somethingElse " + arg);
  }
}

 

 

import java.lang.reflect.*;

class DynamicProxyHandler implements InvocationHandler {
	private Object proxied;

	public DynamicProxyHandler(Object proxied) {
		this.proxied = proxied;
	}

	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("**** proxy: " + proxy.getClass() + ", method: "
				+ method + ", args: " + args);
		if (args != null)
			for (Object arg : args)
				System.out.println("  " + arg);
		return method.invoke(proxied, args);
	}
}

public class SimpleDynamicProxy {
	public static void consumer(Interface iface) {
		iface.doSomething();
		iface.somethingElse("bonobo");
	}

	public static void main(String[] args) {
		RealObject real = new RealObject();
		consumer(real);
		// Insert a proxy and call again:
		Interface proxy = (Interface) Proxy.newProxyInstance(Interface.class
				.getClassLoader(), new Class[] { Interface.class },
				new DynamicProxyHandler(real));
		consumer(proxy);
	}
}

 当我们查看java.lang.reflect.Proxy源码,我们发现起核心作用的是ProxyGenerator.generateProxyClass(String paramString, Class[] paramArrayOfClass),最令人疑惑的问题是,代理对象和如何调用DynamicProxyHandler的invoke方法的,从源码里面我们很难发现如何处理的,对于ProxyGenerator写了一个测试类ProxyClassFile

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import sun.misc.ProxyGenerator;

public class ProxyClassFile {

	public static void main(String[] args) {

		String proxyName = "SimpleDynamicProxy";

		RealObject t = new RealObject();

		Class[] interfaces = t.getClass().getInterfaces();

		byte[] proxyClassFile = ProxyGenerator.generateProxyClass(

		proxyName, interfaces);

		File f = new File("E:/workspace/TIJ4/bin/typeinfo/SimpleDynamicProxy.class");

		try {

			FileOutputStream fos = new FileOutputStream(f);

			fos.write(proxyClassFile);

			fos.flush();

			fos.close();

		} catch (FileNotFoundException e) {

			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.

		} catch (IOException e) {

			e.printStackTrace(); // To change body of catch statement use File |
									// Settings | File Templates.

		}

	}

}

 

反编译SimpleDynamicProxy.class,代码初看起来有点复杂,仔细观察还是很有规律的,将SimpleDynamicProxy5个方法都重定向到invoke()方法,equals(),hashCode()和toString()都是父类Object方法,doSomething()和somethingElse()为接口方法。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import typeinfo.Interface;

public final class SimpleDynamicProxy extends Proxy
  implements Interface
{
  private static Method m1;
  private static Method m0;
  private static Method m3;
  private static Method m4;
  private static Method m2;

  public SimpleDynamicProxy(InvocationHandler paramInvocationHandler)
    throws 
  {
    super(paramInvocationHandler);
  }

  public final boolean equals(Object paramObject)
    throws 
  {
    try
    {
      return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final int hashCode()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m0, null)).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void doSomething()
    throws 
  {
    try
    {
      this.h.invoke(this, m3, null);
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final void somethingElse(String paramString)
    throws 
  {
    try
    {
      this.h.invoke(this, m4, new Object[] { paramString });
      return;
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final String toString()
    throws 
  {
    try
    {
      return (String)this.h.invoke(this, m2, null);
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  static
  {
    try
    {
      m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
      m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
      m3 = Class.forName("typeinfo.Interface").getMethod("doSomething", new Class[0]);
      m4 = Class.forName("typeinfo.Interface").getMethod("somethingElse", new Class[] { Class.forName("java.lang.String") });
      m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
      return;
    }
    catch (NoSuchMethodException localNoSuchMethodException)
    {
      throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
    }
    catch (ClassNotFoundException localClassNotFoundException)
    {
      throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
    }
  }
}

 通过源代码我们不难看出,代理类是如何调用invoke方法的了。

分享到:
评论
5 楼 xiangkun 2010-06-03  
smzd 写道
网管不删广告,只会关我小黑屋,我已经不怕了



我也不怕了!!
4 楼 meiowei 2010-06-03  
eye的管理员效率也不高啊~~~~
3 楼 smzd 2010-06-03  
网管不删广告,只会关我小黑屋,我已经不怕了
2 楼 zhangshixi 2010-06-03  
Arron.li 写道
xu547465458 写道
磁带存储\磁盘存储设备的,维保、销售、系统化服务商    www.storage81.com

专业从事磁带机、磁带库、磁盘阵列、信息化建设、存储系统的业务,全方位提供网络数据安全解决方案和系统集成服务。

     作为一家具有较强综合实力的公司目前主要代理如下产品:
               
                 HP公司磁带机、磁带库等存储系统增值代理;
                 IBM公司磁带机、磁带库存储系统中国代理;
                 Quantum公司存储产品最佳合作伙伴;
                 Veritas、Bakbone、备份软件代理;
                 EMC、SUN磁盘阵列产品专业代理;
                 网络视频监控服务器
                 专业磁盘存储厂商
Tel:021-62111580   62113278
Mobile:13636302561沪、13761648996、
Mail: info@storage81.com
QQ:873372631

竟然有人在这里做广告,要怎么把它删掉

这个家伙到处乱贴,请管理员速度封其号。
1 楼 Arron.li 2010-06-03  
xu547465458 写道
磁带存储\磁盘存储设备的,维保、销售、系统化服务商    www.storage81.com

专业从事磁带机、磁带库、磁盘阵列、信息化建设、存储系统的业务,全方位提供网络数据安全解决方案和系统集成服务。

     作为一家具有较强综合实力的公司目前主要代理如下产品:
               
                 HP公司磁带机、磁带库等存储系统增值代理;
                 IBM公司磁带机、磁带库存储系统中国代理;
                 Quantum公司存储产品最佳合作伙伴;
                 Veritas、Bakbone、备份软件代理;
                 EMC、SUN磁盘阵列产品专业代理;
                 网络视频监控服务器
                 专业磁盘存储厂商
Tel:021-62111580   62113278
Mobile:13636302561沪、13761648996、
Mail: info@storage81.com
QQ:873372631

竟然有人在这里做广告,要怎么把它删掉

相关推荐

Global site tag (gtag.js) - Google Analytics