InvocationHandle的invoke方法
在学习代理模式中接触到了动态代理的相关内容,这是AOP的核心内容。先用一个例子说明 动态代理 的使用
//接口(动态代理只能代理接口)
public interface Subject { public void request();
}
//接口实现 :实现了Subject的request()方法
public class RealSubject implements Subject{ public void request(){ System.out.println("From real subject."); }
}
Inb
//实现了InvocationHandler 接口
public class DynamicSubject implements InvocationHandler
{ private Object obj;//这是动态代理的好处,被封装的对象是Object类型,接受任意类型的对象 public DynamicSubject() { } public DynamicSubject(Object obj) { this.obj = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("before calling " + method); method.invoke(obj, args); System.out.println("after calling " + method); return null; } }
public class Client { public static void main(String[] args) throws Throwable{ // TODO Auto-generated method stub Subject rs=new RealSubject();//这里指定被代理类 InvocationHandler ds=new DynamicSubject(rs); Class<?> cls=rs.getClass(); //生成代理类 ,注意subject是Proxy的子类并且实现了Subject接口的一个类。Subject subject=(Subject) Proxy.newProxyInstance( cls.getClassLoader(),cls.getInterfaces(), ds);
}
以上就是动态代理的使用方法,有一点很奇怪,那就是invoke方法是如何被调用的呢? 可以看到在以上代码中并没有invoke的身影,那是因为有关invoke的调用时在Proxy类中,invoke方法并不是给我们显示的调用,查看源码我们可以看到。
首先看Proxy的静态方法newProxyInstance()
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
throws IllegalArgumentException
{ if (h == null) { throw new NullPointerException(); } /* * Look up or generate the designated proxy class. */ Class cl = getProxyClass(loader, interfaces); /* * Invoke its constructor with the designated invocation handler. */ try { /* * Proxy源码开始有这样的定义: * private final static Class[] constructorParams = { InvocationHandler.class }; * cons即是形参为InvocationHandler类型的构造方法 */ Constructor cons = cl.getConstructor(constructorParams); return (Object) cons.newInstance(new Object[] { h }); //此处返回.} catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } catch (IllegalAccessException e) { throw new InternalError(e.toString()); } catch (InstantiationException e) { throw new InternalError(e.toString()); } catch (InvocationTargetException e) { throw new InternalError(e.toString()); }
}
这个方法实际是利用反射,返回了一个Proxy的子类,实现了指定的接口,返回的类叫做$Proxy0, 这个类包含了invoke的秘密! 请看源码:
public final class $Proxy0 extends Proxy implements Subject { 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("***.RealSubject").getMethod("request", 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()); } } //static public $Proxy0(InvocationHandler invocationhandler) { super(invocationhandler); } @Override public final boolean equals(Object obj) { try { return ((Boolean) super.h.invoke(this, m1, new Object[] { obj })) .booleanValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final int hashCode() { try { return ((Integer) super.h.invoke(this, m0, null)).intValue(); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } public final void request() { try { super.h.invoke(this, m3, null); return; } catch (Error e) { } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } } @Override public final String toString() { try { return (String) super.h.invoke(this, m2, null); } catch (Throwable throwable) { throw new UndeclaredThrowableException(throwable); } }
}
该类中利用反射获取到了4个方法,Object类自带的equals,hasCode,toString ,以及接口Subject的唯一方法request,因此当我们在主函数中调用request.xxx(方法名),就是在$Proxy0类中调用相应方法,每个方法中都有 super.h.invoke(this,m3,null); invoke函数在此起到了作用!
InvocationHandle的invoke方法相关推荐
- Dispatcher.Invoke方法
前一篇小猪分享过在WPF中简单的使用BackgroundWorker完成多线程操作!在那篇中小猪利用了BackgroundWorker组件对耗时比较多的操作放在了单独的BackgroundWorker ...
- JAVA深入研究——Method的Invoke方法。
在写代码的时候,发现Method可以调用子类的对象,但子类即使是改写了的Method,方法名一样,去调用父类的对象也会报错,虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java ...
- invokeRequired属性和 invoke()方法
zt: http://www.x2blog.cn/jinhong618/?tid=22389 问: f (this.InvokeRequired) { ...
- invoke 数组_对于反射中的invoke()方法的理解
作者:码上猿梦http://cnblogs.com/daimajun/p/6545533.html 推荐阅读(点击即可跳转阅读) 1. SpringBoot内容聚合 2. 面试题内容聚合 3. 设计模 ...
- InvocationHandler的invoke方法如何被调用?
关键问题是它们内在的联系.虽然可以看源代码,包括类库.但是把它们抽象出来,有助于理解. 在客户类(即以下代码的Client类),语句Manager managerProxy = (Manager) ...
- invoke方法是做啥的_使用 NLog 给 Asp.Net Core 做请求监控
为了减少由于单个请求挂掉而拖垮整站的情况发生,给所有请求做统计是一个不错的解决方法,通过观察哪些请求的耗时比较长,我们就可以找到对应的接口.代码.数据表,做有针对性的优化可以提高效率.在 asp.ne ...
- invoke方法_JVM是如何执行方法调用的?
前不久在写代码的时候,我不小心踩到一个可变长参数的坑.你或许已经猜到了,它正是可变长参数方法的重载造成的. 我把踩坑的过程放在了文稿里,你可以点击查看. void invoke(Object obj, ...
- 深入理解Java中的反射机制和使用原理!详细解析invoke方法的执行和使用
反射的概念 反射:Refelection,反射是Java的特征之一,允许运行中的Java程序获取自身信息,并可以操作类或者对象的内部属性 通过反射,可以在运行时获得程序或者程序中的每一个类型的成员活成 ...
- 反射之invoke方法
当获得类对应的Class对象后,可以通过getMethods()方法得到全部方法--返回Method数组,或者getMethod()方法来获取指定方法--Method对象. 可以通过Method对象的 ...
最新文章
- 如何使用 UserAccountControl 标志操纵用户帐户属性
- 用Xwt构建跨平台应用程序[转载]
- stylus导入时 报错These relative modules were not found
- 20个Flutter实例视频教程-第03节: 不规则底部工具栏制作-1
- linux-用户管理190919
- 《pytorch》对CIFAR数据集的分类
- python tkinter画笑脸_python – 如何在tkinter窗口中绘制图像
- Android GridView如何适配不同屏幕
- python 成员运算符_Python的“ in”和“ not in”成员资格运算符
- Windows下的命令行。
- 【ESRI论坛6周年征文】ArcEngine注记(Anno/ Label/Element等)处理专题 -入门篇
- HTML5+CSS大作业——清新春暖花开个人博客网站(6页)
- android手机内存单位 吉字节,内存容量单位换算(手机内存单位大小排列换算)
- 开发部程序员绩效考核办法
- 【VBA研究】智力游戏-蓝色方块
- iconst、bipush、sipush、ldc指令的区别
- 分享一个颜色渐变的网站
- 安装win 7 + ubuntu 16.04 双系统安装
- 更名通知 || 初心未改,只为更好,好嗨游戏来了
- ET199加密方案——文件MD5校验
热门文章
- 怎么将迅捷思维导图添加小表情
- 2017年4月9日 星期日 --出埃及记 Exodus 25:7
- 三态门有一个信号控制端en_单片机基础电路
- 华硕路由ax86u 梅林_“亮眼”功能体验!华硕新品路由RT-AX86U评测
- 面向物联网的 23 个开源软件项目
- 【代码】QQ群最近聊天记录做成词云
- excel表格打印每页都有表头_Excel表格技巧—解决打印没有表格线的问题
- 主成分分析 PCA 应用实例 鸢尾花数据集
- 邮件服务器 之 利用debian sarge和postfix 2.1构建媲美ISP的邮件系统
- Failed to decode downloaded font