Java Proxy学习总结
来源:互联网 发布:mac怎么循环播放视频 编辑:程序博客网 时间:2024/06/07 05:44
昨天看了JDK动态代理实现,不是很明白,想知道代理类是怎么实现的,它里面有哪些成员和方法,为什么调用InvocationHandler的invoke方法会得到自动调用。带着这些问题我在网上查阅了资料,现在将自己所理解的JDK动态代理整理一下。
1.先来看下动态代理实现中需要的关键类和方法
1)一个处理方法调用的Handler
public class JdkDbQueryHandler implements InvocationHandler{private IDBQuery real = null; //主题接口实例public JdkDbQueryHandler(IDBQuery real) //会传递一个真实主题的对象{this.real = real;}/** * 参数method代表动态代理实例中被调用的方法 */@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable{Object result = method.invoke(real, args);return result;}}
2)一个生成代理类实例$Proxy0的方法
// 使用JDK的动态代理生成代理对象public static IDBQuery createJdkProxy(){IDBQuery jdkProxy = (IDBQuery) Proxy.newProxyInstance( ClassLoader.getSystemClassLoader(),new Class[] { IDBQuery.class }, new JdkDbQueryHandler());return jdkProxy;}
那么,当我们调用createJdbProxy()方法得到代理类实例,即调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)这个方法时发生了什么了?
a)调用Proxy的newProxyInstance()方法后,首先根据loader和interfaces两个参数得到实现interfaces接口且继承Proxy类的Class对象c1
b)接着调用c1的getConstructor(Class<?>... parameterTypes)方法,InvocationHandler.class作为参数得到Constructor对象
c)调用Constructor的Object newInstance(Constructor<?> cons, InvocationHandler h),在该方法中调用cons.newInstance(new Object[]{h})方法生成代理类的实例(此时调用了父类Proxy的构造方法Proxy(InvocationHandler h)为Proxy中的属性InvocationHandler赋值)。并且用interfaces参数遍历其所有接口的方法,并生成Method对象初始化代理类中的几个Method成员变量.
d)通过传入的第一个参数classloder将刚生成的类加载到jvm中。
2.调用关系
当我们通过createJdkProxy()方法得到代理类的实例且调用interfaces接口中的某个方法时,比如代理类q调用了request()方法,在代理类重写接口的方法request()中有这么一条语句 super.h.invoke(this, m3, null); 到这里相信大家都会明白了,也就是说,当我们调用代理类中的方法时,会调用父类Proxy的InvocationHandler类型属性的invoke(Object proxy,Method method,Object[] args)方法,也就是JdkDbQueryHandler中的invoke()方法。
从上面的分析中可知InvocationHandler中的invoke()方法参数Object proxy其实就是我们生成的代理类对象,但是为什么在JdkDbQueryHandler的invoke()方法中我们没有使用该对象而是使用真实主题的对象了?假如我们就使用proxy对象。我们来分析下:首先,我们是调用了代理类$Proxy0的request()方法,在该方法中调用了InvocationHandler的invoke()方法,如果InvocationHandler的invoke方法写成method.invoke(proxy, args); 这就是调用代理类的method对象所指定,也就是request方法,那此时是不是又调用了InvocationHandler的invoke()方法,这样就会进入死循环。解决的办法是使用我给的实例代码这种写法,传递一个真实主题的实例,那么当method.invoke(real, args);时,就会调用真实主题的method所对应的方法。
本文整理资料来自于:
http://blog.csdn.net/rokii/article/details/4046098
http://hi.baidu.com/malecu/item/9e0edc115cb597a1feded5a0
- Java Proxy学习总结
- Java基础学习总结——动态代理技术(Proxy)
- JAVA Proxy(代理) 学习
- Java动态代理Proxy学习
- java基础总结32-代理(Proxy)
- java 动态代理学习(Proxy,InvocationHandler)
- java 动态代理深度学习(Proxy,InvocationHandler)
- java 动态代理学习(Proxy,InvocationHandler)
- java 动态代理深度学习(Proxy,InvocationHandler)
- java 动态代理学习(Proxy,InvocationHandler)
- java 动态代理学习(Proxy,InvocationHandler)
- java 动态代理学习(Proxy,InvocationHandler)
- Proxy学习
- java Proxy
- JAVA Proxy
- java Proxy
- Java Proxy
- java proxy
- 我第一次领男朋友回家,看到家里掉了多少年的玻璃安
- mysql压力测试
- 自考《信息系统开发与管理》之泛读概总
- BZOJ3670 [Noi2014]动物园
- mysql 配置向导
- Java Proxy学习总结
- SDUTOJ【2780】 pots---bfs
- spring技术内幕17-Spring HTTP调用器实现远程调用
- FFmpeg转码指令(测试通过)
- HDU 4891 The Great Pan(模拟)
- HDU[1253]--bfs
- BZOJ3671 [Noi2014]随机数生成器
- hdu1010 dfs
- CF 17B Hierarchy