概述
Hadoop远程过程调用实现使用Java动态代理和新输入1输出系统(NewInput/Output,NIO)
Java动态代理类位于java.lang.reflect包下,主要包括java.lang rlfct.Proxy和java.lang.reflect.InvocationHandler
代理对象两大任务
- 创建代理接口
实现由java.lang,reflect.Proxy完成
- 调用转发
通过java.lang.reflect.InvocationHandler的实例完成
代理接口的创建
在Java中,代理对象往往实现和目标对象-致的接口,并作为目标对象的代替,接收对
象用户(Client) 的调用,并将全部或部分调用转发给目标对象
代理也是拥有和目标对象一样的权利的‘人’, 简单的说, 代理可以越俎代庖。实际上他是调用转发,将这个任务交给有权利实施的人
代理时序图
java.lang.eflct.Proxy提供了用于创建动态代理类和对象的静态方法。也就是说,通过java.lang.reflect.Proxy可以动态地创建某个接口实现
java.lang.eflct.Proxy比较重要的方法
public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces)
获得代理类的java.lang.Class对象。该代理类将定义在指定的类加载器(参数loader)中,并将实现参数interfaces指定所有接口
注意: 这个类只创建一次,如果再次传入相同的loader和interfaces给newProxyInstance()方法,获得的也只是第一次调用创建的那个java.lang.Class对象
通过Proxy.getProxyClass()获得的代理类都包含一个构造函数,该构造函数需要一个java.lang.reflect.InvocationHandler 的实例
如何获取Proxy对象?,请看以下代码
1 2 3 4 5 6
| Class clss = Proxy.getProxyClass(loader, interfaces);
Constructor constructor = clss.getConstructor(new Class[]{InvocationHandler.class});
Object proxy = constructor.newInstance(new Object[]{invocationHandler});
|
public static boolean isProxyClass(Class<?> cl)
判断java.lang.Class对象是否是代理类
public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException
获取代理实例对应的调用处理程序(即构建代理传入的InvocationHandler实例)
调用转发
InvocationHandler调用实例也叫调用句柄实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
|
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null; }
|
Method类中的invoke方法声明如下
1 2 3
| public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
|
假设目标对象为target,实现转发代码如下
1 2 3
| public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(target, args); s}
|
Java动态代理实例
实例类图
代码
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class DPStatus { String name;
public DPStatus(String name) { this.name = name; }
@Override public String toString() { return "Hello, " + name + "!"; } }
|
1 2 3 4 5 6 7 8
|
public interface PDQueryStatus { public DPStatus getStatus(); }
|
1 2 3 4 5 6 7 8 9 10 11
|
public class DPQueryStatusImpl implements PDQueryStatus{ @Override public DPStatus getStatus() { return new DPStatus("Bitty"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.text.MessageFormat; import java.util.Arrays;
public class DPInvocationHandler implements InvocationHandler {
private DPQueryStatusImpl dpqs;
public DPInvocationHandler(DPQueryStatusImpl dpqs) { this.dpqs = dpqs; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String msg = MessageFormat.format("Calling method", method.getName(), Arrays.toString(args));
System.out.println(msg);
Object res = method.invoke(dpqs, args);
return res; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
public class DPMain { public static PDQueryStatus create(DPQueryStatusImpl dpqs){
Class<?>[] interfaces = new Class[]{PDQueryStatus.class}; DPInvocationHandler handler = new DPInvocationHandler(dpqs);
return (PDQueryStatus) Proxy.newProxyInstance(dpqs.getClass().getClassLoader(), interfaces, handler);
} }
|
1 2 3 4 5 6 7 8 9
| public class Demo { public static void main(String[] args) throws Exception {
PDQueryStatus pdqs = DPMain.create(new DPQueryStatusImpl()); System.out.println(pdqs.getStatus());
} }
|