最近在研究hadoop源码,用到了java动态代理,所以总结一下。
(1)设计模式之代理模式(proxy)
发明代理模式的主要动机是:为目标对象提供访问控制。
需要这种控制的理由有多种比如:1.要访问的对象在远程的机器上(远程代理 remote proxy)2.在需要的时候才真正创建开销比较大的对象(虚代理virtual proxy)3.用于保护目标对象,使得不同客户端在访问目标对象时有不同的访问权限(保护代理protection proxy),4.对目标对象功能的丰富,即在目标对象已有功能的基础上添加用户需要的功能(比如只能指引smart reference)
代理模式的结构图如下:
(2)Java 动态代理
代理分为静态代理和动态代理,静态代理:代理类在运行前已经生产。动态代理:代理类根据需要在运行时创建。
静态代理类例子参考:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html
Java中动态代理分为两步:1.接受client的调用,2. 将调用转发给目标对象
在Java中的动态代理使用了java.lang.reflact.Proxy和java.lang.reflact.InvocationHandler. 其中Proxy用于创建动态代理类和对象,InvocationHandler主要用于调用转发.
Proxy类:
Proxy提供静态方法用于创建代理类和代理接口 ,其函数原型:
public static Object newProxyInstance(ClassLoader loader, Class>[] interfaces, InvocationHandler h) throws llegalArgumentException
参数说明:
ClassLoader loader:类加载器,代理类定义在该类加载器中
Class>[] interfaces:代理类要实现的接口,一般和委托类的接口一样(设计模式-代理模式结构图中可以看出来)
InvocationHandler h:得到InvocationHandler接口的子类实例
Ps:类加载器 (直接摘抄自:http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html)
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器;
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的;
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。
InvocationHandler接口:
public interface InvocationHandler {
public Object invoke(Object proxy,Method method,Object[] args) throws Throwable;
}
Object proxy:代理对象本身
Method method:用户调用的代理对象上的方法
Object[] args:方法调用时所需要的参数
Invoke返回值作为代理对象的返回值返回给client。在真正实现代理的时候,InvocationHandler会调用Method的invoke
(3)参考:
《hadoop技术内幕-深入解析Hadoop Common和HDFS架构设计与实现原理》. 蔡斌,陈湘萍. 机械工业出版社
《hadoop技术内幕-深入解析MapReduce架构设计与实现原理》. 董西成. 机械工业出版社
《设计模式-可复用面向对象软件的基础》. Erich Gamma, Richard Helm,Ralph Johnson,John Vlissides. 机械工业出版社
http://www.cnblogs.com/kid-li/archive/2006/10/18/532192.html
http://alaric.iteye.com/blog/1913048
http://www.cnblogs.com/jqyp/archive/2010/08/20/1805041.html