最近在看Dubbo 服务框架, 通过RPC 实现了输入和输出,并支持与Spring无缝结合。
做的很不错。
其中:ServiceProvider,ServiceConsumer
服务提供者需要输入输出的接口和实现;
服务消费者 只需要接口。
现在看了梁飞的日志,自己理解了一下他的代码,自己敲了一遍,理解了一下。
记录下来。
package com.mjp.rpc.study.rpcframe;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.ServerSocket;
import java.net.Socket;
public class RpcFramework {
/**
* @param service
* @param port
* @return
* @throws Exception
*/
public static Object serverInvoke(final Object service, int port) throws Exception {
if (service == null) {
throw new IllegalArgumentException(" service is null");
}
if (port < 1 || port > 65535) {
throw new IllegalArgumentException(" port is not valid must in 1-65535");
}
ServerSocket server = new ServerSocket(port);
while (true) {
try {
final Socket socket = server.accept();
new Thread(new Runnable() {
@Override
public void run() {
ObjectOutputStream outs = null;
ObjectInputStream input = null;
try {
input = new ObjectInputStream(socket.getInputStream());
String methodName = input.readUTF();
Class<?>[] parameters = (Class<?>[])input.readObject();
Object[] arguments = (Object[])input.readObject();
outs = new ObjectOutputStream(socket.getOutputStream());
Method method = service.getClass().getMethod(methodName, parameters);
Object result = method.invoke(service, arguments);
outs.writeObject(result);
} catch (Exception ex) {
if(outs != null){
try {
outs.writeObject(ex);
} catch (Exception e) {
}
}
}finally{
if(outs != null){
try {
outs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(input != null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}).start();
Thread.sleep(100);
} catch (Exception ex) {
}
}
}
/**
* @param interfaceClass
* @param host
* @param port
* @return
* @throws Exception
*/
public static <T> T refer(final Class<T> interfaceClass ,final String host ,final int port) throws Exception{
if(interfaceClass == null){
throw new IllegalAccessException("interfaceClass is null");
}
if(host == null || host.trim().length() == 0){
throw new IllegalAccessException("host is null");
}
if (port < 1 || port > 65535) {
throw new IllegalArgumentException(" port is not valid must in 1-65535");
}
return (T)Proxy.newProxyInstance(interfaceClass.getClassLoader(),new Class<?>[]{interfaceClass},new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Socket socket = new Socket(host,port);
ObjectOutputStream outs = null;
try{
outs = new ObjectOutputStream(socket.getOutputStream());
outs.writeUTF(method.getName());
outs.writeObject(method.getParameterTypes());
outs.writeObject(args);
ObjectInputStream input = null;
try{
input = new ObjectInputStream(socket.getInputStream());
Object result = input.readObject();
if(result instanceof Throwable){
throw (Throwable)result;
}
return result;
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(input != null){
input.close();
}
}
}catch(Exception ex){
ex.printStackTrace();
}finally{
if(outs != null){
outs.close();
}
}
return null;
}
});
}
}
package com.mjp.rpc.study.rpcframe;
public class RpcProvider {
public static void main(String[] args) throws Exception{
ITestService service = new TestServiceImpl();
RpcFramework.serverInvoke(service, 2000);
}
}
package com.mjp.rpc.study.rpcframe;
public class RpcConsumer {
public static void main(String[] args) throws Exception {
ITestService service = RpcFramework.refer(ITestService.class, "localhost", 2000);
String result = service.helloWorld("mojianpo");
System.out.println(result);
}
}
package com.mjp.rpc.study.rpcframe;
public class RpcConsumer {
public static void main(String[] args) throws Exception {
ITestService service = RpcFramework.refer(ITestService.class, "localhost", 2000);
String result = service.helloWorld("mojianpo");
System.out.println(result);
}
}
----------------------------------
package com.mjp.rpc.study.rpcframe;
public interface ITestService {
public String helloWorld(String name);
}
package com.mjp.rpc.study.rpcframe;
public class TestServiceImpl implements ITestService{
@Override
public String helloWorld(String name) {
return "hello world :" + name;
}
}