Java动态代理实现

动态代理定义

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException {
}

参数类型解释
newProxyInstance方法
返回值: Object是interface的实例
参数: ClassLoader类加载器,interfaces实现的接口数组,InvocationHandler接口对象

使用方式
通过Proxy类的newProxyInstance静态方法即可获取到接口对象,
通过对象的方法调用即可实现对动态代理类真正的方法调用。

举例

public interface Test{//接口类Test
			List<String> test1(String str);
			List<Integer> test2(int id);
		}
		
		Object object = Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{Test.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return null;
            }
        });
        Test test = (Test)object;
        List<String> list = test.test1("ss");
	
	1、定义接口类Test
	2、通过Proxy.newProxyInstance方法获取对象Object
	3、Object对象强转为Test对象test
	4、test.test1("ss")方法调用实现对代理类的对应方法调用
	5、上一步的test1方法调用之后,InvocationHandler接口的invoke方法被回调(此处可实现自己的逻辑)

设计

	对生成的object对象打印object.getClass().getName() 输出结果:com.sun.proxy.$Proxy0
	可见$Proxy0类便是动态代理机制为我们自动生成的类,该类继承Proxy,实现Test接口,所以object对象可以强转为Test对象
	生成$Proxy0类的技术采用字节码操作技术(目前存在Javassist ASM Cglib 其中Cglib是对ASM的封装版)		
	以上,产生的$Proxy0类的存在对使用者隐藏,而是通过InvocationHandler接口把外部的Test接口与内部的$Proxy0联系起来。
	再说如何联系:
	使用JDK代码ProxyGenerator.generateProxyClass("aa", new Class[]{Test.class});
	便获取到代理类$Proxy0的字节流,再保存到文件之后如下:
	
public final class aa extends Proxy implements Test{
		  private static Method m1;
		  private static Method m3;
		  private static Method m2;
		  private static Method m4;
		  private static Method m0;
		  
		  public final List test1(String paramString)
		  {
			try
			{
			  return (List)this.h.invoke(this, m3, new Object[] { paramString });
			}
			catch (Error|RuntimeException localError)
			{
			  throw localError;
			}
			catch (Throwable localThrowable)
			{
			  throw new UndeclaredThrowableException(localThrowable);
			}
		  }
		}

	通过代码可知:举例中第4步test.test1("ss")的调用其实是调用了aa类的test1的方法,而this.h就是
	newProxyInstance的第三个参数,所以举例中第4步的调用使得第5步InvocationHandler接口的invoke方法被回调
	
	其中,ProxyGenerator类在Android Studio中不可见(需要自行下载rt.jar对应的类重新编译),可使用IDEA查看
	关于字节码操作技术可参考 https://mp.csdn.net/mdeditor/87877612#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值