1、 java中的动态代理模式:
Dynamic Proxy是由两个class实现的:java.lang.reflect.Proxy 和 java.lang.reflect.InvocationHandler,后者是一个接口(interface)。
所谓动态代理原理就是:对于继承了java.lang.reflect.Proxy的类,在调用方法时会将调用的主动权交给实现了java.lang.reflect.InvocationHandler接口的类。
例子:
代理类:
public class TaskAgent implements InvocationHandler {
private Object obj = null;
public TaskAgent(Object obj) {
this.obj = obj;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return method.invoke(obj, args);
}
}
业务接口:
public interface SayHello {
public void sayHello();
}
实现业务接口:
public class ManSayHello implements SayHello {
public void sayHello() {
System.out.println("I am a man");
}
}
调用方法:
SayHello sayHello = (SayHello) Proxy.newProxyInstance(Thread
.currentThread().getContextClassLoader(),
new Class[] { SayHello.class },
new TaskAgent(new ManSayHello()));
sayHello.sayHello();
从这个例子可以看出sayHello调用sayHello()方法之后将真正的调用主动权交给了TaskAgent类。
基于这个原理,在RMI通信中,引入动态代理模式,这样当我们调用某一接口(业务功能)的方法时,将这个功能代理给一个远程RMI接口,由于这个RMI对象是一个远程对象,进行远程方法调用。这样做的好处时,业务接口不需要继承Remote接口就可以进行远程方法调用,对于业务程序开发人员,只需关心业务程序,与RMI无关。
改写代理类TaskAgent:
public class TaskAgent implements InvocationHandler {
private CommonTask commonTask = null;
public TaskAgent(CommonTask commonTask,String taskName) {
this. commonTask = commonTask;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return commonTask.executeTask(taskName, method.getName(),method.getParameterTypes(), args);
}
}
CommonTask 类为一个继承了Remote接口的远程接口,可以进行远程方法调用。在改进的TaskAgent类中,会将调用的主动权交给commonTask远程对象,commonTask远程对象调用远程方法executeTask。executeTask方法利用java反射机制,在服务端执行业务功能。通过这个代理,业务接口及时实现都不需要继承Remote接口,就可进行远程方法调用。