在说rpc之前,先简单说一下java的动态代理。jdk提供了基于接口的动态代理,只需要调用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h),需要传入三个参数,第一个是类加载器,第二个被代理的接口,第三个是InvocationHandler,最关键就在于InvocationHandler接口的invoke方法怎么去实现,当通过代理类调用其实现的接口的某个方法时,内部就是调用invoke方法。
比如定义了一个接口HelloService
package com.kibear.proxy;
public interface HelloService {
String sayHello(String msg);
}
定义了一个InvocationHandler的实现类HelloInvocationHandler
package com.kibear.proxy;
import java.lang.reflect.InvocationHandler;
public class HelloInvocationHandler implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return "Hello world";
}
}
写一个main方法
package com.kibear.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class HeloWorld {
public static void main(String[] args) {
InvocationHandler h = new HelloInvocationHandler();
HelloService helloService = (HelloService) Proxy.newProxyInstance(HeloWorld.class.getClassLoader(),
new Class<?>[] { HelloService.class }, h);
String result = helloService.sayHello("");
System.out.println(result);// Hello World
}
}
可以看出动态代理自动产生了一个HelloService的代理对象,不需要自己去写HelloService的实现类,jdk帮我做了,我们只需要在invoke中写逻辑就行了。
RPC最主要就是网络通信和动态代理,当rpc服务启动以后,客户端这边只有接口,要调用服务端这个接口的具体实现的时候,就需要通过动态代理去产生这个接口的一个代理对象,调用方法的时候,就会调用InvocationHandler的invoke方法,所以invoke的实现就特别重要了。invoke方法里面要封装好网络通信,需要把方法名,接口,方法参数等信息传递到服务端,这样服务端就可以找到这个接口的具体实现类去调用方法,然后把返回值通过网络发送到客户端,完成整个rpc的调用。