动态代理

简单的说,有A类,现在希望在A类的函数print()中增加Log类的功能log(),但是不能修改A类源码,因为用户手中只有A类的.class文件,于是提供了动态代理的方法,即新建一个动态代理类A_proxy继承A类,同时新建一个处理类InLog继承InvocationHandler, 然后重写InLog的invoke函数,首先增加log()的功能,然后调用method.invoke()激发print()函数,实际执行的时候,

A a = (A)Proxy.newProxyInstance(

    getClass().getClassLoader(), // 1. 类加载器

    new Class<?>[] {A.class}, // 2. 代理需要实现的接口,可以有多个

    new InLog(new A_proxy()));

 

然后调用的时候执行a.print()即可

 

注意以下问题:

1. a 的实际类型是jdkproxy.$Proxy* ,是动态生成的。

2. 对代理对象a的所有.print()函数调用,最终都会被转发到InvocationHandler.invoke()并执行内部逻辑.

通过以上方式,对原有print()函数的功能增加需求就被转移到了A_proxy这个代理类中,用户使用的时候只需要在创建

对象时执行:

A a = (A)Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[] {A.class}, new InLog(new A_proxy()));

则生成的a对象就增加了日志的功能,而a的实际类型A_proxy又是动态生成的,

讲白了,同多态这种静态代理的方式不同,多态实现的时候,子类在编译期即被加载,

动态代理虽然也是通过接口实现不同类和对象之间的运行,但是指针指向的类并不是编译时决定的,而是实际执行时生成的类和对象,该对象拦截了执行的方法,并调用了InvocationHandler.invoke()里面的处理逻辑,就相当于把A_proxy的print()调用代理到了InvocationHandler中,因此称之为动态代理。

参考:http://www.importnew.com/27772.html

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值