Proxy 动态代理再次理解

原创 2012年03月27日 14:19:06
package reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import static java.lang.System.out;
interface User{
	public abstract void say(String str);
}
class UUU implements User{
	@Override
	public void say(String str) {
		out.print(str);
	}
}
public class ProxyTest {
	public   Object target = null;
	public static void main(String args[])throws Exception {
		//System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true"); // 通过此语句得到动态生成 的class 文件,然后通过 反编译工具得到代码 
		User prox = (User)(new ProxyTest().bind(new UUU()));// 动态得到 proxy类,这个类继承proxy,且实现User 接口
		
	}
	public static void  proxyConstruct()throws Exception
	{
		Class<?> clazz =  Proxy.getProxyClass(Comparable.class.getClassLoader(),Comparable.class);
		Constructor cons = clazz.getConstructor(InvocationHandler.class);
		Object proxy = cons.newInstance(new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				
				return null;
			}
		});
		out.println(proxy.toString());
	}
	public static void proxyInstance()throws Exception {
		Object proxy = Proxy.newProxyInstance(Comparable.class.getClassLoader(),new Class<?>[] {Comparable.class},new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
		});
		out.println(proxy==null);
	}
	public Object bind(final Object target)
	{
		this.target = target ;
		return Proxy.newProxyInstance(Comparable.class.getClassLoader(),new Class<?>[] {Comparable.class},new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				out.println("begin:");
				return method.invoke(target, args); // 对于代理所执行的任何方法都将转移到这个地址执行,这也是就为什么可以添加功能的原因 
			}
		});
	}
}

/*
 * 			Proxy 原理 
 * 	 Proxy 就是动态生成一个,其实 这和代理并没有什么关系,它只是可以动态地去生成一个类,在生成
 * 	 这个类的时候,我们可以规定它的加载器,实现的接口,而Proxy 生成的这个类并代理目标类做什么,所以里面还有一个重要的成员 InvocationHandler h
 * 
 *  下面我们来分析一下  目标类(target)、代理类(proxy)、InvocationHandler(Handler)类 它们之间的关系 		
 * 		
 * 		当我们调用代理类中实现接口的方法时,如proxy.add(),会将方法名传给 代理类的 InvocationHandler 成员,而这个成员有一个 invoke 方法,所以我们
 * 		调用 proxy.add 则成了 h.invoke(this,method,args);而调用h.invoke方法,又不得不调用我们实现的invocationHandler接口里面的 invoke 方法,
 * 		而我们则在 handler.invoke 方法中调用 根据传过来的方法Method调用  Method.invoke(target,args),即,这样就成功调用了目标类里的方法
 * 		
 * 		因为代理类调用的所有的方法都变了 h.invoke(proxy,method,args)调用方法,而在invoke 中又知道了方法的method ,即让方法调用对象 method.invoke(target,args)
 * 		因为代理类始终是自己,所以就变成了h.inovoke(this,method,args)
 * 
 * */

下面是反编译得到的动态类,实现Comparable 接口

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

public final class Proxy0 extends Proxy
  implements Comparable
{
  private static Method m3;
  private static Method m1;
  private static Method m0;
  private static Method m2;

  public Proxy0()
    throws 
  {
    super(paramInvocationHandler);
  }

  public final int compareTo()
    throws 
  {
    try
    {
      return ((Integer)this.h.invoke(this, m3, new Object[] { paramObject })).intValue();
    }
    catch (RuntimeException localRuntimeException)
    {
      throw localRuntimeException;
    }
    catch (Throwable localThrowable)
    {
      throw new UndeclaredThrowableException(localThrowable);
    }
  }

  public final boolean equals()
    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 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
    {
      m3 = Class.forName("java.lang.Comparable").getMethod("compareTo", new Class[] { Class.forName("java.lang.Object") });
      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]);
      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());
    }
  }
}



 

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

Java 动态代理实现解析

Java动态代理只能针对接口进行动态代理。如果需要对类进行实现代理可以使用:CGLIB,ASM等相关的操作字节码实现(在这里先只介绍下SUN 基于接口动态代理的实现)。 代码如下: import ja...

ProxyFactory

package reflect; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; imp...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

java 动态代理高级

从JDK1.3以后,java引入动态代理机制,即对目标对象的方法调用是通过代理对象来完成的,java的动态代理只能针对接口进行动态代理,即要实现动态代理的类必须实现接口,CGLIB提供了针对类的动态代...

JD-GUI反编译后代码逻辑分析

一,用jd-gui.exe等工具查看源代码。如何你不会,可以参看此文章: http://blog.csdn.net/hp_2008/article/details/8207879  可...

反编译与反汇编

反编译做的就是编译的相反动作。举例来说,例如一个程序用C语言来写,写完之后要编译成CPU可以识别和运行的机器代码,也就是生成EXE程序。而反编译是反过来,把EXE反编译成编程源代码,也就是C程序,不过...

导入某些特殊Jar包中的类

导入特殊jar设置 在通常的开发中可能会去看下API的源代码,自己有时候也可以模仿API中的源代码做一些研究,可是有些特殊jar包中的类报无法导入的错误: The import sun.misc....
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)