Java Proxy InvocationHandler invoke理解

来源:互联网 发布:switch网络一会b一会f 编辑:程序博客网 时间:2024/05/16 14:46

原文地址:点击打开链接

一.相关类及其方法:

java.lang.reflect.Proxy,
Proxy 提供用于创建动态代理类和实例的静态方法.
newProxyInstance()

Returns an instance of a proxy class for the specified interfaces that dispatches method invocations to the specified invocation handler. This method is equivalent to:      Proxy.getProxyClass(loader, interfaces).         getConstructor(new Class[] { InvocationHandler.class }).         newInstance(new Object[] { handler }); Proxy.newProxyInstance throws IllegalArgumentException for the same reasons that Proxy.getProxyClass does.
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

java.lang.reflect.InvocationHandler,
InvocationHandler 是代理实例的调用处理程序 实现的接口。 
invoke()
在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

二.源代码:

被代理对象的接口及实现类:

public interface Manager {public void modify();}
//接口实现类public class ManagerImpl implements Manager {@Overridepublic void modify() {System.out.println("*******modify()方法被调用");}}
业务代理类

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class BusinessHandler implements InvocationHandler {private Object object = null;public BusinessHandler(Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("do something before method");Object ret = method.invoke(this.object, args);System.out.println("do something after method");return ret;}}
客户端类

import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {// 元对象(被代理对象)ManagerImpl managerImpl = new ManagerImpl();// 业务代理类BusinessHandler securityHandler = new BusinessHandler(managerImpl);// 获得代理类($Proxy0 extends Proxy implements Manager)的实例.Manager managerProxy = (Manager) Proxy.newProxyInstance(managerImpl.getClass().getClassLoader(), managerImpl.getClass().getInterfaces(), securityHandler);managerProxy.modify();}}
三.执行结果:
do something before method*******modify()方法被调用do something after method

四.机制分析:

Proxy.(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)做了以下几件事.
(1)根据参数loader和interfaces调用方法 getProxyClass(loader, interfaces)创建代理类$Proxy.
$Proxy0类实现了interfaces的接口,并继承了Proxy类.
(2)实例化$Proxy0并在构造方法中把BusinessHandler传过去,接着$Proxy0调用父类Proxy的构造器,为h赋值,如下:
class Proxy{
   InvocationHandler h=null;
   protected Proxy(InvocationHandler h) {
    this.h = h;
   }
   ...
}

下面是本例的$Proxy0类的源码(好不容易才把它提出来):

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 Manager {private static Method m1;private static Method m0;private static Method m3;private static Method m2;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("com.ml.test.Manager").getMethod("modify",new Class[0]);m2 = Class.forName("java.lang.Object").getMethod("toString",new Class[0]);} catch (NoSuchMethodException nosuchmethodexception) {throw new NoSuchMethodError(nosuchmethodexception.getMessage());} catch (ClassNotFoundException classnotfoundexception) {throw new NoClassDefFoundError(classnotfoundexception.getMessage());}}public $Proxy0(InvocationHandler invocationhandler) {super(invocationhandler);}@Overridepublic final boolean equals(Object obj) {try {return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })).booleanValue();} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}@Overridepublic final int hashCode() {try {return ((Integer) super.h.invoke(this, m0, null)).intValue();} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}public final void modify() {try {super.h.invoke(this, m3, null);return;} catch (Error e) {} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}@Overridepublic final String toString() {try {return (String) super.h.invoke(this, m2, null);} catch (Throwable throwable) {throw new UndeclaredThrowableException(throwable);}}}
接着把得到的$Proxy0实例强制转换成Manager.
当执行managerProxy.modify()方法时,就调用了$Proxy0类中的modify()方法.
在modify方法中,调用父类Proxy中的h的invoke()方法.
即InvocationHandler.invoke();








0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 玩战争前线总是闪退怎么办 uu加速器卡在29怎么办 新ipad下载不了东西怎么办 福昕pdf阅读器找不到图章怎么办 战地4没达到分数怎么办 植物在太暗环境怎么办 玩绝地求生机型不支持怎么办 安卓安装包损坏怎么办 方舟手游安装包损坏怎么办 7p新机耗电快怎么办 不小心把图片删了怎么办 腿上毛又长又多怎么办 征兵体检体重太轻怎么办 体检发现颈部有淋巴节怎么办? 4岁宝宝汗毛重怎么办 嘴巴张开闭不上怎么办 口张开闭不上怎么办 要去当兵有痔疮怎么办 狗舔的东西吃了怎么办 婚检说生过孩子怎么办 劳动法规定身体有疾病的怎么办 铁路对职工醉驾怎么办 入职体检高血糖怎么办 睾丸捏一下很疼怎么办 小孩睾丸受外力红肿该怎么办 睾丸炎症怎么办啊会不会不育呢 腰疼连着睾丸疼怎么办 为什么结石会睾丸疼怎么办 感觉自己睾丸变小了怎么办 宝宝小丁丁肿了怎么办 两岁宝宝高低肩怎么办 参军体检视力不过关怎么办 验兵视力不过关怎么办 军检了感冒了怎么办 双侧附睾头囊肿怎么办 睾丸上面长疙瘩很痒都抓烂了怎么办 睾丸小引起精子数量少怎么办 睾丸发育不完全精子存活率低怎么办 踢到睾丸很痛怎么办 兔子的睾丸烂了怎么办 梗阻性无精穿刺取得精子不好怎么办