天上满是飞机

闻道有先后,术业有专攻,仅此而已

Proxy 动态代理再次理解

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基础
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭